From owner-FreeBSD-users-jp@jp.freebsd.org  Wed Apr 11 14:31:01 2001
Received: (from daemon@localhost)
	by castle.jp.freebsd.org (8.9.3+3.2W/8.7.3) id OAA85699;
	Wed, 11 Apr 2001 14:31:01 +0900 (JST)
	(envelope-from owner-FreeBSD-users-jp@jp.FreeBSD.org)
Received: from pop3.tky.3web.ne.jp (root@pop3.tky.3web.ne.jp [210.155.161.17])
	by castle.jp.freebsd.org (8.9.3+3.2W/8.7.3) with ESMTP id OAA85692
	for <FreeBSD-users-jp@jp.freebsd.org>; Wed, 11 Apr 2001 14:31:00 +0900 (JST)
	(envelope-from takuroho@tky3.3web.ne.jp)
Received: from localhost (1Cust33.tnt6.tko2.da.uu.net [63.12.64.33])
	by pop3.tky.3web.ne.jp (8.9.3+3.2W/POP3.TKY) with ESMTP id OAA09395;
	Wed, 11 Apr 2001 14:30:48 +0900 (JST)
Date: Wed, 11 Apr 2001 14:25:23 +0900 (JST)
Message-Id: <20010411.142523.78705530.takuroho@tky3.3web.ne.jp>
To: FreeBSD-users-jp@jp.freebsd.org
Cc: bsd-nomads@clave.gr.jp
From: Takuro Horikawa (=?iso-2022-jp?B?GyRCS1lAbhsoQiAbJEJCc086GyhC?=) <takuroho@tky3.3web.ne.jp>
In-Reply-To: <20010411141005M.goto@ee.saga-u.ac.jp>
References: <20010411141005M.goto@ee.saga-u.ac.jp>
X-Mailer: Mew version 1.95b119 on Emacs 21.0 / Mule 5.0 (SAKAKI)
Mime-Version: 1.0
Content-Type: Multipart/Mixed; boundary="--Next_Part(Wed_Apr_11_14:25:23_2001_835)--"
Content-Transfer-Encoding: 7bit
Reply-To: FreeBSD-users-jp@jp.freebsd.org
Precedence: list
X-Distribute: distribute version 2.1 (Alpha) patchlevel 24e+010328
X-Sequence: FreeBSD-users-jp 60744
Subject: [FreeBSD-users-jp 60744] Re: Libretto100
 =?ISO-2022-JP?B?GyRCJEckTiVVJW0lQyVUITwkTjtITVEbKEI=?= 
Errors-To: owner-FreeBSD-users-jp@jp.freebsd.org
Sender: owner-FreeBSD-users-jp@jp.freebsd.org
X-Originator: takuroho@tky3.3web.ne.jp

----Next_Part(Wed_Apr_11_14:25:23_2001_835)--
Content-Type: Text/Plain; charset=iso-2022-jp
Content-Transfer-Encoding: 7bit

$BKY@n$G$9!#(B


From: Satoru GOTO <goto@ee.saga-u.ac.jp>
Subject: [FreeBSD-users-jp 60742] Libretto100 $B$G$N%U%m%C%T!<$N;HMQ(B 
Date: Wed, 11 Apr 2001 14:10:05 +0900

> pccardd[48]: Card "Y_E DATA"("External FDD") [Controller] [2.00]
> matched "Y-E DATA" ("External FDD") [(null)] [(null)]
> pccardd[48]: driver allocation failed for Y-E Data(External FDD):
> Device not configured
$B$3$l!"(Bcurrent $B$@$HF~$C$F$$$F$^$@(B mfc $B$5$l$FL5$$$s$G$9$h!#(B
$B8D?ME*$K(B 4-stable $B$K(B mfc $B$9$k(B patch $B$r;H$C$F$^$9!#(B
----------------------------------------
$BKY@n!!BsO:!!(Btakuroho@tky3.3web.ne.jp

----Next_Part(Wed_Apr_11_14:25:23_2001_835)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="4-stable-fd.diff"

*** sys/isa/fd.c.orig	Sat Jan  8 18:33:06 2000
--- sys/isa/fd.c	Wed May 17 20:49:14 2000
***************
*** 52,57 ****
--- 52,58 ----
   */
  
  #include "opt_fdc.h"
+ #include "card.h"
  
  #include <sys/param.h>
  #include <sys/systm.h>
***************
*** 286,296 ****
  }
  
  static void
! fdctl_wr(fdc_p fdc, u_int8_t v)
  {
  	bus_space_write_1(fdc->ctlt, fdc->ctlh, 0, v);
  }
  
  #if 0
  
  static u_int8_t
--- 287,303 ----
  }
  
  static void
! fdctl_wr_isa(fdc_p fdc, u_int8_t v)
  {
  	bus_space_write_1(fdc->ctlt, fdc->ctlh, 0, v);
  }
  
+ static void
+ fdctl_wr_pcmcia(fdc_p fdc, u_int8_t v)
+ {
+ 	bus_space_write_1(fdc->portt, fdc->porth, FDCTL+fdc->port_off, v);
+ }
+ 
  #if 0
  
  static u_int8_t
***************
*** 301,382 ****
  
  #endif
  
- #ifdef FDC_YE
- #if NCARD > 0
- #include <sys/select.h>
- #include <sys/module.h>
- #include <pccard/cardinfo.h>
- #include <pccard/driver.h>
- #include <pccard/slot.h>
- 
- /*
-  *	PC-Card (PCMCIA) specific code.
-  */
- static int yeinit(struct pccard_devinfo *);		/* init device */
- static void yeunload(struct pccard_devinfo *); 		/* Disable driver */
- static int yeintr(struct pccard_devinfo *); 		/* Interrupt handler */
- 
- PCCARD_MODULE(fdc, yeinit, yeunload, yeintr, 0, bio_imask);
- 
- /*
-  *	Initialize the device - called from Slot manager.
-  */
- static int yeinit(struct pccard_devinfo *devi)
- {
- 	fdc_p fdc = &fdc_data[devi->isahd.id_unit];
- 
- 	fdc->baseport = devi->isahd.id_iobase;
- 	/*
- 	 * reset controller
- 	 */
- 	fdout_wr(fdc, 0);
- 	DELAY(100);
- 	fdout_wr(fdc, FDO_FRST);
- 
- 	/*
- 	 * wire into system
- 	 */
- 	if (yeattach(&devi->isahd) == 0)
- 		return(ENXIO);
- 
- 	return(0);
- }
- 
- /*
-  *	yeunload - unload the driver and clear the table.
-  *	XXX TODO:
-  *	This is usually called when the card is ejected, but
-  *	can be caused by a modunload of a controller driver.
-  *	The idea is to reset the driver's view of the device
-  *	and ensure that any driver entry points such as
-  *	read and write do not hang.
-  */
- static void yeunload(struct pccard_devinfo *devi)
- {
- 	if (fd_data[devi->isahd.id_unit].type == NO_TYPE)
- 		return;
- 
- 	/*
- 	 * this prevents Fdopen() and fdstrategy() from attempting
- 	 * to access unloaded controller
- 	 */
- 	fd_data[devi->isahd.id_unit].type = NO_TYPE;
- 
- 	printf("fdc%d: unload\n", devi->isahd.id_unit);
- }
- 
- /*
-  *	yeintr - Shared interrupt called from
-  *	front end of PC-Card handler.
-  */
- static int yeintr(struct pccard_devinfo *devi)
- {
- 	fdintr((fdcu_t)devi->isahd.id_unit);
- 	return(1);
- }
- #endif /* NCARD > 0 */
- #endif /* FDC_YE */
- 
  static	d_open_t	Fdopen;	/* NOTE, not fdopen */
  static	d_close_t	fdclose;
  static	d_ioctl_t	fdioctl;
--- 308,313 ----
***************
*** 586,606 ****
  fdc_alloc_resources(struct fdc_data *fdc)
  {
  	device_t dev;
! 	int ispnp;
  
  	dev = fdc->fdc_dev;
! 	ispnp = fdc->fdc_ispnp;
  	fdc->rid_ioport = fdc->rid_irq = fdc->rid_drq = 0;
  	fdc->res_ioport = fdc->res_irq = fdc->res_drq = 0;
  
  	/*
! 	 * We don't just use an 8 port range (e.g. 0x3f0-0x3f7) since that
! 	 * covers an IDE control register at 0x3f6.
  	 * Isn't PC hardware wonderful.
  	 */
  	fdc->res_ioport = bus_alloc_resource(dev, SYS_RES_IOPORT,
  					     &fdc->rid_ioport, 0ul, ~0ul, 
! 					     ispnp ? 1 : 6, RF_ACTIVE);
  	if (fdc->res_ioport == 0) {
  		device_printf(dev, "cannot reserve I/O port range\n");
  		return ENXIO;
--- 517,545 ----
  fdc_alloc_resources(struct fdc_data *fdc)
  {
  	device_t dev;
! 	int ispnp, ispcmcia;
  
  	dev = fdc->fdc_dev;
! 	ispnp = (fdc->flags & FDC_ISPNP) != 0;
! 	ispcmcia = (fdc->flags & FDC_ISPCMCIA) != 0;
  	fdc->rid_ioport = fdc->rid_irq = fdc->rid_drq = 0;
  	fdc->res_ioport = fdc->res_irq = fdc->res_drq = 0;
  
  	/*
! 	 * On standard ISA, we don't just use an 8 port range
! 	 * (e.g. 0x3f0-0x3f7) since that covers an IDE control
! 	 * register at 0x3f6.
! 	 *
  	 * Isn't PC hardware wonderful.
+ 	 *
+ 	 * The Y-E Data PCMCIA FDC doesn't have this problem, it
+ 	 * uses the register with offset 6 for pseudo-DMA, and the
+ 	 * one with offset 7 as control register.
  	 */
  	fdc->res_ioport = bus_alloc_resource(dev, SYS_RES_IOPORT,
  					     &fdc->rid_ioport, 0ul, ~0ul, 
! 					     ispcmcia ? 8 : (ispnp ? 1 : 6),
! 					     RF_ACTIVE);
  	if (fdc->res_ioport == 0) {
  		device_printf(dev, "cannot reserve I/O port range\n");
  		return ENXIO;
***************
*** 608,653 ****
  	fdc->portt = rman_get_bustag(fdc->res_ioport);
  	fdc->porth = rman_get_bushandle(fdc->res_ioport);
  
! 	/*
! 	 * Some BIOSen report the device at 0x3f2-0x3f5,0x3f7 and some at
! 	 * 0x3f0-0x3f5,0x3f7. We detect the former by checking the size
! 	 * and adjust the port address accordingly.
! 	 */
! 	if (bus_get_resource_count(dev, SYS_RES_IOPORT, 0) == 4)
! 		fdc->port_off = -2;
  
! 	/*
! 	 * Register the control port range as rid 1 if it isn't there
! 	 * already. Most PnP BIOSen will have already done this but
! 	 * non-PnP configurations don't.
! 	 *
! 	 * And some (!!) report 0x3f2-0x3f5 and completely leave out the
! 	 * control register!  It seems that some non-antique controller chips
! 	 * have a different method of programming the transfer speed which
! 	 * doesn't require the control register, but it's mighty bogus as the
! 	 * chip still responds to the address for the control register.
! 	 */
! 	if (bus_get_resource_count(dev, SYS_RES_IOPORT, 1) == 0) {
! 		u_long ctlstart;
  
! 		/* Find the control port, usually 0x3f7 */
! 		ctlstart = rman_get_start(fdc->res_ioport) + fdc->port_off + 7;
  
! 		bus_set_resource(dev, SYS_RES_IOPORT, 1, ctlstart, 1);
! 	}
  
! 	/*
! 	 * Now (finally!) allocate the control port.
! 	 */
! 	fdc->rid_ctl = 1;
! 	fdc->res_ctl = bus_alloc_resource(dev, SYS_RES_IOPORT, &fdc->rid_ctl,
! 					  0ul, ~0ul, 1, RF_ACTIVE);
! 	if (fdc->res_ctl == 0) {
! 		device_printf(dev, "cannot reserve control I/O port range\n");
! 		return ENXIO;
  	}
- 	fdc->ctlt = rman_get_bustag(fdc->res_ctl);
- 	fdc->ctlh = rman_get_bushandle(fdc->res_ctl);
  
  	fdc->res_irq = bus_alloc_resource(dev, SYS_RES_IRQ,
  					  &fdc->rid_irq, 0ul, ~0ul, 1, 
--- 547,600 ----
  	fdc->portt = rman_get_bustag(fdc->res_ioport);
  	fdc->porth = rman_get_bushandle(fdc->res_ioport);
  
! 	if (!ispcmcia) {
! 		/*
! 		 * Some BIOSen report the device at 0x3f2-0x3f5,0x3f7
! 		 * and some at 0x3f0-0x3f5,0x3f7. We detect the former
! 		 * by checking the size and adjust the port address
! 		 * accordingly.
! 		 */
! 		if (bus_get_resource_count(dev, SYS_RES_IOPORT, 0) == 4)
! 			fdc->port_off = -2;
  
! 		/*
! 		 * Register the control port range as rid 1 if it
! 		 * isn't there already. Most PnP BIOSen will have
! 		 * already done this but non-PnP configurations don't.
! 		 *
! 		 * And some (!!) report 0x3f2-0x3f5 and completely
! 		 * leave out the control register!  It seems that some
! 		 * non-antique controller chips have a different
! 		 * method of programming the transfer speed which
! 		 * doesn't require the control register, but it's
! 		 * mighty bogus as the chip still responds to the
! 		 * address for the control register.
! 		 */
! 		if (bus_get_resource_count(dev, SYS_RES_IOPORT, 1) == 0) {
! 			u_long ctlstart;
  
! 			/* Find the control port, usually 0x3f7 */
! 			ctlstart = rman_get_start(fdc->res_ioport) +
! 				fdc->port_off + 7;
  
! 			bus_set_resource(dev, SYS_RES_IOPORT, 1, ctlstart, 1);
! 		}
  
! 		/*
! 		 * Now (finally!) allocate the control port.
! 		 */
! 		fdc->rid_ctl = 1;
! 		fdc->res_ctl = bus_alloc_resource(dev, SYS_RES_IOPORT,
! 						  &fdc->rid_ctl,
! 						  0ul, ~0ul, 1, RF_ACTIVE);
! 		if (fdc->res_ctl == 0) {
! 			device_printf(dev,
! 				      "cannot reserve control I/O port range\n");
! 			return ENXIO;
! 		}
! 		fdc->ctlt = rman_get_bustag(fdc->res_ctl);
! 		fdc->ctlh = rman_get_bushandle(fdc->res_ctl);
  	}
  
  	fdc->res_irq = bus_alloc_resource(dev, SYS_RES_IRQ,
  					  &fdc->rid_irq, 0ul, ~0ul, 1, 
***************
*** 656,669 ****
  		device_printf(dev, "cannot reserve interrupt line\n");
  		return ENXIO;
  	}
! 	fdc->res_drq = bus_alloc_resource(dev, SYS_RES_DRQ,
! 					  &fdc->rid_drq, 0ul, ~0ul, 1, 
! 					  RF_ACTIVE);
! 	if (fdc->res_drq == 0) {
! 		device_printf(dev, "cannot reserve DMA request line\n");
! 		return ENXIO;
  	}
- 	fdc->dmachan = fdc->res_drq->r_start;
  
  	return 0;
  }
--- 603,619 ----
  		device_printf(dev, "cannot reserve interrupt line\n");
  		return ENXIO;
  	}
! 
! 	if ((fdc->flags & FDC_NODMA) == 0) {
! 		fdc->res_drq = bus_alloc_resource(dev, SYS_RES_DRQ,
! 						  &fdc->rid_drq, 0ul, ~0ul, 1, 
! 						  RF_ACTIVE);
! 		if (fdc->res_drq == 0) {
! 			device_printf(dev, "cannot reserve DMA request line\n");
! 			return ENXIO;
! 		}
! 		fdc->dmachan = fdc->res_drq->r_start;
  	}
  
  	return 0;
  }
***************
*** 737,748 ****
  	fdc = device_get_softc(dev);
  	bzero(fdc, sizeof *fdc);
  	fdc->fdc_dev = dev;
  
  	/* Check pnp ids */
  	error = ISA_PNP_PROBE(device_get_parent(dev), dev, fdc_ids);
  	if (error == ENXIO)
  		return ENXIO;
! 	fdc->fdc_ispnp = (error == 0);
  
  	/* Attempt to allocate our resources for the duration of the probe */
  	error = fdc_alloc_resources(fdc);
--- 687,700 ----
  	fdc = device_get_softc(dev);
  	bzero(fdc, sizeof *fdc);
  	fdc->fdc_dev = dev;
+ 	fdc->fdctl_wr = fdctl_wr_isa;
  
  	/* Check pnp ids */
  	error = ISA_PNP_PROBE(device_get_parent(dev), dev, fdc_ids);
  	if (error == ENXIO)
  		return ENXIO;
! 	if (error == 0)
! 		fdc->flags |= FDC_ISPNP;
  
  	/* Attempt to allocate our resources for the duration of the probe */
  	error = fdc_alloc_resources(fdc);
***************
*** 788,793 ****
--- 740,812 ----
  	return (error);
  }
  
+ #if NCARD > 0
+ 
+ static int
+ fdc_pccard_probe(device_t dev)
+ {
+ 	int	error;
+ 	struct	fdc_data *fdc;
+ 
+ 	fdc = device_get_softc(dev);
+ 	bzero(fdc, sizeof *fdc);
+ 	fdc->fdc_dev = dev;
+ 	fdc->fdctl_wr = fdctl_wr_pcmcia;
+ 
+ 	fdc->flags |= FDC_ISPCMCIA | FDC_NODMA;
+ 
+ 	/* Attempt to allocate our resources for the duration of the probe */
+ 	error = fdc_alloc_resources(fdc);
+ 	if (error)
+ 		goto out;
+ 
+ 	/* First - lets reset the floppy controller */
+ 	fdout_wr(fdc, 0);
+ 	DELAY(100);
+ 	fdout_wr(fdc, FDO_FRST);
+ 
+ 	/* see if it can handle a command */
+ 	if (fd_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240), 
+ 		   NE7_SPEC_2(2, 0), 0)) {
+ 		error = ENXIO;
+ 		goto out;
+ 	}
+ 
+ 	device_set_desc(dev, "Y-E Data PCMCIA floppy");
+ 	fdc->fdct = FDC_NE765;
+ 
+ out:
+ 	fdc_release_resources(fdc);
+ 	return (error);
+ }
+ 
+ static int
+ fdc_pccard_detach(device_t dev)
+ {
+ 	struct	fdc_data *fdc;
+ 	int	error;
+ 
+ 	fdc = device_get_softc(dev);
+ 
+ 	/* have our children detached first */
+ 	if ((error = bus_generic_detach(dev)))
+ 		return (error);
+ 
+ 	if ((fdc->flags & FDC_ATTACHED) == 0) {
+ 		device_printf(dev, "already unloaded\n");
+ 		return (0);
+ 	}
+ 	fdc->flags &= ~FDC_ATTACHED;
+ 
+ 	BUS_TEARDOWN_INTR(device_get_parent(dev), dev, fdc->res_irq,
+ 			  fdc->fdc_intr);
+ 	fdc_release_resources(fdc);
+ 	device_printf(dev, "unload\n");
+ 	return (0);
+ }
+ 
+ #endif /* NCARD > 0 */
+ 
  /*
   * Add a child device to the fdc controller.  It will then be probed etc.
   */
***************
*** 834,843 ****
  	fdc->fdcu = device_get_unit(dev);
  	fdc->flags |= FDC_ATTACHED;
  
! 	/* Acquire the DMA channel forever, The driver will do the rest */
  				/* XXX should integrate with rman */
! 	isa_dma_acquire(fdc->dmachan);
! 	isa_dmainit(fdc->dmachan, 128 << 3 /* XXX max secsize */);
  	fdc->state = DEVIDLE;
  
  	/* reset controller, turn motor off, clear fdout mirror reg */
--- 853,864 ----
  	fdc->fdcu = device_get_unit(dev);
  	fdc->flags |= FDC_ATTACHED;
  
! 	if ((fdc->flags & FDC_NODMA) == 0) {
! 		/* Acquire the DMA channel forever, The driver will do the rest */
  				/* XXX should integrate with rman */
! 		isa_dma_acquire(fdc->dmachan);
! 		isa_dmainit(fdc->dmachan, 128 << 3 /* XXX max secsize */);
! 	}
  	fdc->state = DEVIDLE;
  
  	/* reset controller, turn motor off, clear fdout mirror reg */
***************
*** 894,899 ****
--- 915,949 ----
  
  DRIVER_MODULE(fdc, isa, fdc_driver, fdc_devclass, 0, 0);
  
+ #if NCARD > 0
+ 
+ static device_method_t fdc_pccard_methods[] = {
+ 	/* Device interface */
+ 	DEVMETHOD(device_probe,		fdc_pccard_probe),
+ 	DEVMETHOD(device_attach,	fdc_attach),
+ 	DEVMETHOD(device_detach,	fdc_pccard_detach),
+ 	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
+ 	DEVMETHOD(device_suspend,	bus_generic_suspend),
+ 	DEVMETHOD(device_resume,	bus_generic_resume),
+ 
+ 	/* Bus interface */
+ 	DEVMETHOD(bus_print_child,	fdc_print_child),
+ 	DEVMETHOD(bus_read_ivar,	fdc_read_ivar),
+ 	/* Our children never use any other bus interface methods. */
+ 
+ 	{ 0, 0 }
+ };
+ 
+ static driver_t fdc_pccard_driver = {
+ 	"fdc",
+ 	fdc_pccard_methods,
+ 	sizeof(struct fdc_data)
+ };
+ 
+ DRIVER_MODULE(fdc, pccard, fdc_pccard_driver, fdc_devclass, 0, 0);
+ 
+ #endif /* NCARD > 0 */
+ 
  /******************************************************************/
  /*
   * devices attached to the controller section.  
***************
*** 922,928 ****
  	/* look up what bios thinks we have */
  	switch (fd->fdu) {
  	case 0:
! 		if (device_get_flags(fdc->fdc_dev) & FDC_PRETEND_D0)
  			fdt = RTCFDT_144M | RTCFDT_144M_PRETENDED;
  		else
  			fdt = (rtcin(RTC_FDISKETTE) & 0xf0);
--- 972,980 ----
  	/* look up what bios thinks we have */
  	switch (fd->fdu) {
  	case 0:
! 		if ((fdc->flags & FDC_ISPCMCIA))
! 			fdt = RTCFDT_144M;
! 		else if (device_get_flags(fdc->fdc_dev) & FDC_PRETEND_D0)
  			fdt = RTCFDT_144M | RTCFDT_144M_PRETENDED;
  		else
  			fdt = (rtcin(RTC_FDISKETTE) & 0xf0);
***************
*** 1069,1079 ****
  	return (0);
  }
  
  static device_method_t fd_methods[] = {
  	/* Device interface */
  	DEVMETHOD(device_probe,		fd_probe),
  	DEVMETHOD(device_attach,	fd_attach),
! 	DEVMETHOD(device_detach,	bus_generic_detach),
  	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
  	DEVMETHOD(device_suspend,	bus_generic_suspend), /* XXX */
  	DEVMETHOD(device_resume,	bus_generic_resume), /* XXX */
--- 1121,1142 ----
  	return (0);
  }
  
+ static int
+ fd_detach(device_t dev)
+ {
+ 	struct	fd_data *fd;
+ 
+ 	fd = device_get_softc(dev);
+ 	untimeout(fd_turnoff, fd, fd->toffhandle);
+ 
+ 	return (0);
+ }
+ 
  static device_method_t fd_methods[] = {
  	/* Device interface */
  	DEVMETHOD(device_probe,		fd_probe),
  	DEVMETHOD(device_attach,	fd_attach),
! 	DEVMETHOD(device_detach,	fd_detach),
  	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
  	DEVMETHOD(device_suspend,	bus_generic_suspend), /* XXX */
  	DEVMETHOD(device_resume,	bus_generic_resume), /* XXX */
***************
*** 1089,1188 ****
  
  DRIVER_MODULE(fd, fdc, fd_driver, fd_devclass, 0, 0);
  
- /******************************************************************/
- 
- #ifdef FDC_YE
- /*
-  * this is a subset of fdattach() optimized for the Y-E Data
-  * PCMCIA floppy drive.
-  */
- static int yeattach(struct isa_device *dev)
- {
- 	fdcu_t  fdcu = dev->id_unit;
- 	fdc_p   fdc = fdc_data + fdcu;
- 	fdsu_t  fdsu = 0;               /* assume 1 drive per YE controller */
- 	fdu_t   fdu;
- 	fd_p    fd;
- 	int     st0, st3, i;
- 	fdc->fdcu = fdcu;
- 	/*
- 	 * the FDC_NODMA flag is used to to indicate special PIO is used
- 	 * instead of DMA
- 	 */
- 	fdc->flags = FDC_ATTACHED|FDC_NODMA;
- 	fdc->state = DEVIDLE;
- 	/* reset controller, turn motor off, clear fdout mirror reg */
- 	fdout_wr(fdc, ((fdc->fdout = 0)));
- 	bufq_init(&fdc->head);
- 	/*
- 	 * assume 2 drives/ "normal" controller
- 	 */
- 	fdu = fdcu * 2;
- 	if (fdu >= NFD) {
- 		printf("fdu %d >= NFD\n",fdu);
- 		return(0);
- 	};
- 	fd = &fd_data[fdu];
- 
- 	set_motor(fdcu, fdsu, TURNON);
- 	DELAY(1000000); /* 1 sec */
- 	fdc->fdct = FDC_NE765;
- 
- 	if ((fd_cmd(fdcu, 2, NE7CMD_SENSED, fdsu, 1, &st3) == 0) &&
- 		(st3 & NE7_ST3_T0)) {
- 		/* if at track 0, first seek inwards */
- 		/* seek some steps: */
- 		(void)fd_cmd(fdcu, 3, NE7CMD_SEEK, fdsu, 10, 0);
- 		DELAY(300000); /* ...wait a moment... */
- 		(void)fd_sense_int(fdc, 0, 0); /* make ctrlr happy */
- 	}
- 
- 	/* If we're at track 0 first seek inwards. */
- 	if ((fd_sense_drive_status(fdc, &st3) == 0) && (st3 & NE7_ST3_T0)) {
- 		/* Seek some steps... */
- 		if (fd_cmd(fdcu, 3, NE7CMD_SEEK, fdsu, 10, 0) == 0) {
- 			/* ...wait a moment... */
- 			DELAY(300000);
- 			/* make ctrlr happy: */
- 			(void)fd_sense_int(fdc, 0, 0);
- 		}
- 	}
- 
- 	for(i = 0; i < 2; i++) {
- 		/*
- 		 * we must recalibrate twice, just in case the
- 		 * heads have been beyond cylinder 76, since most
- 		 * FDCs still barf when attempting to recalibrate
- 		 * more than 77 steps
- 		 */
- 		/* go back to 0: */
- 		if (fd_cmd(fdcu, 2, NE7CMD_RECAL, fdsu, 0) == 0) {
- 			/* a second being enough for full stroke seek*/
- 			DELAY(i == 0? 1000000: 300000);
- 
- 			/* anything responding? */
- 			if (fd_sense_int(fdc, &st0, 0) == 0 &&
- 				(st0 & NE7_ST0_EC) == 0)
- 				break; /* already probed succesfully */
- 		}
- 	}
- 
- 	set_motor(fdcu, fdsu, TURNOFF);
- 
- 	if (st0 & NE7_ST0_EC) /* no track 0 -> no drive present */
- 		return(0);
- 
- 	fd->track = FD_NO_TRACK;
- 	fd->fdc = fdc;
- 	fd->fdsu = fdsu;
- 	fd->options = 0;
- 	printf("fdc%d: 1.44MB 3.5in PCMCIA\n", fdcu);
- 	fd->type = FD_1440;
- 
- 	return (1);
- }
- #endif
- 
  /****************************************************************************/
  /*                            motor control stuff                           */
  /*		remember to not deselect the drive we're working on         */
--- 1152,1157 ----
***************
*** 1237,1253 ****
  
  	TRACE1("[fd%d: turnoff]", fd->fdu);
  
  	/*
  	 * Don't turn off the motor yet if the drive is active.
! 	 * XXX shouldn't even schedule turnoff until drive is inactive
! 	 * and nothing is queued on it.
  	 */
  	if (fd->fdc->state != DEVIDLE && fd->fdc->fdu == fd->fdu) {
! 		fd->toffhandle = timeout(fd_turnoff, fd, 4 * hz);
  		return;
  	}
  
- 	s = splbio();
  	fd->flags &= ~FD_MOTOR;
  	set_motor(fd->fdc, fd->fdsu, TURNOFF);
  	splx(s);
--- 1206,1226 ----
  
  	TRACE1("[fd%d: turnoff]", fd->fdu);
  
+ 	s = splbio();
  	/*
  	 * Don't turn off the motor yet if the drive is active.
! 	 *
! 	 * If we got here, this could only mean we missed an interrupt.
! 	 * This can e. g. happen on the Y-E Date PCMCIA floppy controller
! 	 * after a controller reset.  Just schedule a pseudo-interrupt
! 	 * so the state machine gets re-entered.
  	 */
  	if (fd->fdc->state != DEVIDLE && fd->fdc->fdu == fd->fdu) {
! 		fdc_intr(fd->fdc);
! 		splx(s);
  		return;
  	}
  
  	fd->flags &= ~FD_MOTOR;
  	set_motor(fd->fdc, fd->fdsu, TURNOFF);
  	splx(s);
***************
*** 1453,1460 ****
  	}
  	fd->ft = fd_types + type - 1;
  	fd->flags |= FD_OPEN;
! 	device_busy(fd->dev);
! 	device_busy(fd->fdc->fdc_dev);
  	return 0;
  }
  
--- 1426,1432 ----
  	}
  	fd->ft = fd_types + type - 1;
  	fd->flags |= FD_OPEN;
! 
  	return 0;
  }
  
***************
*** 1547,1552 ****
--- 1519,1525 ----
  
  	/* Tell devstat we are starting on the transaction */
  	devstat_start_transaction(&fd->device_stats);
+ 	device_busy(fd->dev);
  
  	fdstart(fdc);
  	splx(s);
***************
*** 1731,1737 ****
  		fd->skip = 0;
  		fdc->fd = fd;
  		fdc->fdu = fdu;
! 		fdctl_wr(fdc, fd->ft->trans);
  		TRACE1("[0x%x->FDCTL]", fd->ft->trans);
  		/*******************************************************\
  		* If the next drive has a motor startup pending, then	*
--- 1704,1710 ----
  		fd->skip = 0;
  		fdc->fd = fd;
  		fdc->fdu = fdu;
! 		fdc->fdctl_wr(fdc, fd->ft->trans);
  		TRACE1("[0x%x->FDCTL]", fd->ft->trans);
  		/*******************************************************\
  		* If the next drive has a motor startup pending, then	*
***************
*** 1867,1875 ****
  			if(fd_sense_drive_status(fdc, &st3) != 0)
  			{
  				/* stuck controller? */
! 				isa_dmadone(bp->b_flags, bp->b_data + fd->skip,
! 					    format ? bp->b_bcount : fdblk,
! 					    fdc->dmachan);
  				fdc->retry = 6;	/* reset the beast */
  				return (retrier(fdc));
  			}
--- 1840,1850 ----
  			if(fd_sense_drive_status(fdc, &st3) != 0)
  			{
  				/* stuck controller? */
! 				if (!(fdc->flags & FDC_NODMA))
! 					isa_dmadone(bp->b_flags,
! 						    bp->b_data + fd->skip,
! 						    format ? bp->b_bcount : fdblk,
! 						    fdc->dmachan);
  				fdc->retry = 6;	/* reset the beast */
  				return (retrier(fdc));
  			}
***************
*** 1895,1904 ****
  		}
  
  		if (format) {
! 			if (fdc->flags & FDC_NODMA)
  				(void)fdcpio(fdc,bp->b_flags,
  					bp->b_data+fd->skip,
  					bp->b_bcount);
  			/* formatting */
  			if(fd_cmd(fdc, 6,  NE7CMD_FORMAT, head << 2 | fdu,
  				  finfo->fd_formb_secshift,
--- 1870,1895 ----
  		}
  
  		if (format) {
! 			if (fdc->flags & FDC_NODMA) {
! 				/*
! 				 * This seems to be necessary for
! 				 * whatever obscure reason; if we omit
! 				 * it, we end up filling the sector ID
! 				 * fields of the newly formatted track
! 				 * entirely with garbage, causing
! 				 * `wrong cylinder' errors all over
! 				 * the place when trying to read them
! 				 * back.
! 				 *
! 				 * Umpf.
! 				 */
! 				SET_BCDR(fdc, 1, bp->b_bcount, 0);
! 
  				(void)fdcpio(fdc,bp->b_flags,
  					bp->b_data+fd->skip,
  					bp->b_bcount);
+ 
+ 			}
  			/* formatting */
  			if(fd_cmd(fdc, 6,  NE7CMD_FORMAT, head << 2 | fdu,
  				  finfo->fd_formb_secshift,
***************
*** 1906,1914 ****
  				  finfo->fd_formb_gaplen,
  				  finfo->fd_formb_fillbyte, 0)) {
  				/* controller fell over */
! 				isa_dmadone(bp->b_flags, bp->b_data + fd->skip,
! 					    format ? bp->b_bcount : fdblk,
! 					    fdc->dmachan);
  				fdc->retry = 6;
  				return (retrier(fdc));
  			}
--- 1897,1907 ----
  				  finfo->fd_formb_gaplen,
  				  finfo->fd_formb_fillbyte, 0)) {
  				/* controller fell over */
! 				if (!(fdc->flags & FDC_NODMA))
! 					isa_dmadone(bp->b_flags,
! 						    bp->b_data + fd->skip,
! 						    format ? bp->b_bcount : fdblk,
! 						    fdc->dmachan);
  				fdc->retry = 6;
  				return (retrier(fdc));
  			}
***************
*** 1941,1949 ****
  				   fd->ft->datalen,  /* data length */
  				   0)) {
  				/* the beast is sleeping again */
! 				isa_dmadone(bp->b_flags, bp->b_data + fd->skip,
! 					    format ? bp->b_bcount : fdblk,
! 					    fdc->dmachan);
  				fdc->retry = 6;
  				return (retrier(fdc));
  			}
--- 1934,1944 ----
  				   fd->ft->datalen,  /* data length */
  				   0)) {
  				/* the beast is sleeping again */
! 				if (!(fdc->flags & FDC_NODMA))
! 					isa_dmadone(bp->b_flags,
! 						    bp->b_data + fd->skip,
! 						    format ? bp->b_bcount : fdblk,
! 						    fdc->dmachan);
  				fdc->retry = 6;
  				return (retrier(fdc));
  			}
***************
*** 1978,1986 ****
  		untimeout(fd_iotimeout, fdc, fd->tohandle);
  
  		if (fd_read_status(fdc, fd->fdsu)) {
! 			isa_dmadone(bp->b_flags, bp->b_data + fd->skip,
! 				    format ? bp->b_bcount : fdblk,
! 				    fdc->dmachan);
  			if (fdc->retry < 6)
  				fdc->retry = 6;	/* force a reset */
  			return (retrier(fdc));
--- 1973,1982 ----
  		untimeout(fd_iotimeout, fdc, fd->tohandle);
  
  		if (fd_read_status(fdc, fd->fdsu)) {
! 			if (!(fdc->flags & FDC_NODMA))
! 				isa_dmadone(bp->b_flags, bp->b_data + fd->skip,
! 					    format ? bp->b_bcount : fdblk,
! 					    fdc->dmachan);
  			if (fdc->retry < 6)
  				fdc->retry = 6;	/* force a reset */
  			return (retrier(fdc));
***************
*** 2025,2030 ****
--- 2021,2027 ----
  			/* ALL DONE */
  			fd->skip = 0;
  			fdc->bp = NULL;
+ 			device_unbusy(fd->dev);
  			devstat_end_transaction_buf(&fd->device_stats, bp);
  			biodone(bp);
  			fdc->fd = (fd_p) 0;
***************
*** 2189,2194 ****
--- 2186,2192 ----
  		bp->b_resid += bp->b_bcount - fdc->fd->skip;
  		fdc->bp = NULL;
  		fdc->fd->skip = 0;
+ 		device_unbusy(fd->dev);
  		devstat_end_transaction_buf(&fdc->fd->device_stats, bp);
  		biodone(bp);
  		fdc->state = FINDWORK;
***************
*** 2257,2262 ****
--- 2255,2261 ----
  	if (rv == EWOULDBLOCK) {
  		/* timed out */
  		rv = EIO;
+ 		device_unbusy(fd->dev);
  		biodone(bp);
  	}
  	if (bp->b_flags & B_ERROR)
*** sys/isa/fdc.h.orig	Mon Jan 10 02:13:35 2000
--- sys/isa/fdc.h	Wed May 17 20:55:12 2000
***************
*** 54,59 ****
--- 54,61 ----
  #define FDC_HAS_FIFO	0x10
  #define FDC_NEEDS_RESET	0x20
  #define FDC_NODMA	0x40
+ #define FDC_ISPNP	0x80
+ #define FDC_ISPCMCIA	0x100
  	struct	fd_data *fd;
  	int	fdu;		/* the active drive	*/
  	int	state;
***************
*** 73,79 ****
  	bus_space_handle_t ctlh;
  	void	*fdc_intr;
  	struct	device *fdc_dev;
! 	int	fdc_ispnp;
  };
  
  /***********************************************************************\
--- 75,81 ----
  	bus_space_handle_t ctlh;
  	void	*fdc_intr;
  	struct	device *fdc_dev;
! 	void	(*fdctl_wr)(struct fdc_data *fdc, u_int8_t v);
  };
  
  /***********************************************************************\

----Next_Part(Wed_Apr_11_14:25:23_2001_835)----
