diff options
Diffstat (limited to 'sys/dev')
40 files changed, 1791 insertions, 1012 deletions
diff --git a/sys/dev/aha/aha_isa.c b/sys/dev/aha/aha_isa.c index 94266790e87f..c3704df34e03 100644 --- a/sys/dev/aha/aha_isa.c +++ b/sys/dev/aha/aha_isa.c @@ -28,7 +28,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: aha_isa.c,v 1.5 1998/11/10 06:44:54 gibbs Exp $ + * $Id: aha_isa.c,v 1.6 1999/01/20 06:21:23 imp Exp $ */ #include "pnp.h" @@ -257,7 +257,6 @@ static void ahapnp_attach(u_long csn, u_long vend_id, char *name, struct isa_device *dev) { struct pnp_cinfo d; - struct isa_device *dvp; if (dev->id_unit >= NAHATOT) return; @@ -278,9 +277,7 @@ ahapnp_attach(u_long csn, u_long vend_id, char *name, struct isa_device *dev) if (dev->id_driver == NULL) { dev->id_driver = &ahadriver; - dvp = find_isadev(isa_devtab_tty, &ahadriver, 0); - if (dvp != NULL) - dev->id_id = dvp->id_id; + dev->id_id = isa_compat_nextid(); } if ((dev->id_alive = aha_isa_probe(dev)) != 0) diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index 680c33495386..4bee8d3f4ea8 100644 --- a/sys/dev/ata/ata-all.c +++ b/sys/dev/ata/ata-all.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: ata-all.c,v 1.5 1999/03/28 18:57:18 sos Exp $ + * $Id: ata-all.c,v 1.6 1999/04/10 18:53:35 sos Exp $ */ #include "ata.h" @@ -44,12 +44,18 @@ #include <vm/vm.h> #include <vm/pmap.h> #include <machine/clock.h> +#ifdef __i386__ #include <machine/smp.h> +#endif #include <pci/pcivar.h> #include <pci/pcireg.h> +#ifdef __i386__ #include <i386/isa/icu.h> #include <i386/isa/isa.h> #include <i386/isa/isa_device.h> +#else +#include <isa/isareg.h> +#endif #include <dev/ata/ata-all.h> #include <dev/ata/ata-disk.h> #include <dev/ata/atapi-all.h> @@ -62,7 +68,7 @@ #endif /* prototypes */ -#if NISA > 0 +#if NISA > 0 && defined(__i386__) static int32_t ata_isaprobe(struct isa_device *); static int32_t ata_isaattach(struct isa_device *); #endif @@ -76,9 +82,10 @@ static void ataintr(int32_t); static int32_t atanlun = 0; struct ata_softc *atadevices[MAXATA]; + +#if NISA > 0 && defined(__i386__) struct isa_driver atadriver = { ata_isaprobe, ata_isaattach, "ata" }; -#if NISA > 0 static int32_t ata_isaprobe(struct isa_device *devp) { @@ -133,6 +140,10 @@ ata_pciprobe(pcici_t tag, pcidi_t type) return "Promise Ultra/33 IDE controller"; case 0x522910b9: return "AcerLabs Aladdin IDE controller"; + case 0x06401095: + return "CMD 640 IDE controller"; + case 0x06461095: + return "CMD 646 IDE controller"; #if 0 case 0x05711106: return "VIA Apollo IDE controller"; @@ -222,14 +233,18 @@ ata_pciattach(pcici_t tag, int32_t unit) lun = 0; if (ata_probe(iobase_1, altiobase_1, bmaddr_1, tag, &lun)) { if (iobase_1 == IO_WD1) +#ifdef __i386__ register_intr(irq1, (int)"", 0, (inthand2_t *)ataintr, &bio_imask, lun); +#else + alpha_platform_setup_ide_intr(0, ataintr, (void *)(intptr_t)lun); +#endif else { if (sysctrl) pci_map_int(tag, (inthand2_t *)promise_intr, - (void *)lun, &bio_imask); + (void *)(intptr_t)lun, &bio_imask); else - pci_map_int(tag, (inthand2_t *)ataintr, (void *)lun,&bio_imask); + pci_map_int(tag, (inthand2_t *)ataintr, (void *)(intptr_t)lun,&bio_imask); } printf("ata%d at 0x%04x irq %d on ata-pci%d\n", lun, iobase_1, isa_apic_irq(irq1), unit); @@ -237,11 +252,15 @@ ata_pciattach(pcici_t tag, int32_t unit) lun = 1; if (ata_probe(iobase_2, altiobase_2, bmaddr_2, tag, &lun)) { if (iobase_2 == IO_WD2) +#ifdef __i386__ register_intr(irq2, (int)"", 0, (inthand2_t *)ataintr, &bio_imask, lun); +#else + alpha_platform_setup_ide_intr(1, ataintr, (void *)(intptr_t)lun); +#endif else { if (!sysctrl) - pci_map_int(tag, (inthand2_t *)ataintr, (void *)lun,&bio_imask); + pci_map_int(tag, (inthand2_t *)ataintr, (void *)(intptr_t)lun,&bio_imask); } printf("ata%d at 0x%04x irq %d on ata-pci%d\n", lun, iobase_2, isa_apic_irq(irq2), unit); @@ -418,6 +437,7 @@ ata_probe(int32_t ioaddr, int32_t altioaddr, int32_t bmaddr, #ifndef ATA_STATIC_ID atanlun++; #endif + outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_MASTER); return ATA_IOSIZE; } @@ -571,7 +591,7 @@ printf("ata_command: addr=%04x, device=%02x, cmd=%02x, c=%d, h=%d, s=%d, count=% scp->active = ATA_WAIT_INTR; outb(scp->ioaddr + ATA_CMD, command); if (tsleep((caddr_t)scp, PRIBIO, "atacmd", 500)) { - printf("ata_command: timeout waiting for interrupt"); + printf("ata_command: timeout waiting for interrupt\n"); scp->active = ATA_IDLE; return -1; } diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c index c5f7a418041e..c5efe55f58d4 100644 --- a/sys/dev/ata/ata-disk.c +++ b/sys/dev/ata/ata-disk.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: ata-disk.c,v 1.5 1999/03/28 18:57:18 sos Exp $ + * $Id: ata-disk.c,v 1.6 1999/04/10 18:53:35 sos Exp $ */ #include "ata.h" @@ -527,11 +527,11 @@ ad_transfer(struct buf *bp) /* output the data */ #if 0 outsw(adp->controller->ioaddr + ATA_DATA, - (void *)((int32_t)bp->b_data + adp->donecount), + (void *)((uintptr_t)bp->b_data + adp->donecount), adp->currentsize / sizeof(int16_t)); #else outsl(adp->controller->ioaddr + ATA_DATA, - (void *)((int32_t)bp->b_data + adp->donecount), + (void *)((uintptr_t)bp->b_data + adp->donecount), adp->currentsize / sizeof(int32_t)); #endif adp->bytecount -= adp->currentsize; @@ -590,11 +590,11 @@ oops: /* data ready, read in */ #if 0 insw(adp->controller->ioaddr + ATA_DATA, - (void *)((int32_t)bp->b_data + adp->donecount), + (void *)((uintptr_t)bp->b_data + adp->donecount), adp->currentsize / sizeof(int16_t)); #else insl(adp->controller->ioaddr + ATA_DATA, - (void *)((int32_t)bp->b_data + adp->donecount), + (void *)((uintptr_t)bp->b_data + adp->donecount), adp->currentsize / sizeof(int32_t)); #endif adp->bytecount -= adp->currentsize; diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c index fe0a08c56447..0886dbe7340d 100644 --- a/sys/dev/ata/ata-dma.c +++ b/sys/dev/ata/ata-dma.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: ata-dma.c,v 1.3 1999/03/30 13:09:47 sos Exp $ + * $Id: ata-dma.c,v 1.4 1999/04/10 18:53:35 sos Exp $ */ #include "ata.h" @@ -42,6 +42,12 @@ #include <pci/pcireg.h> #include <dev/ata/ata-all.h> +#ifdef __alpha__ +#undef vtophys +#define vtophys(va) (pmap_kextract(((vm_offset_t) (va))) \ + + 1*1024*1024*1024) +#endif + /* misc defines */ #define MIN(a,b) ((a)>(b)?(b):(a)) @@ -64,7 +70,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device, if (!(dmatab = malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT))) return -1; - if (((int)dmatab>>PAGE_SHIFT)^(((int)dmatab+PAGE_SIZE-1)>>PAGE_SHIFT)) { + if (((uintptr_t)dmatab>>PAGE_SHIFT)^(((uintptr_t)dmatab+PAGE_SIZE-1)>>PAGE_SHIFT)) { printf("ata_dmainit: dmatab crosses page boundary, no DMA\n"); free(dmatab, M_DEVBUF); return -1; @@ -252,7 +258,7 @@ ata_dmasetup(struct ata_softc *scp, int32_t device, #ifdef ATA_DEBUGDMA printf("ata%d: dmasetup\n", scp->lun); #endif - if (((u_int32_t)data & 1) || (count & 1)) + if (((uintptr_t)data & 1) || (count & 1)) return -1; if (!count) { @@ -263,7 +269,7 @@ ata_dmasetup(struct ata_softc *scp, int32_t device, dmatab = scp->dmatab[device ? 1 : 0]; dma_base = vtophys(data); - dma_count = MIN(count, (PAGE_SIZE - ((u_int32_t)data & PAGE_MASK))); + dma_count = MIN(count, (PAGE_SIZE - ((uintptr_t)data & PAGE_MASK))); data += dma_count; count -= dma_count; diff --git a/sys/dev/ata/atapi-all.c b/sys/dev/ata/atapi-all.c index 63224756ab02..3b4896609d74 100644 --- a/sys/dev/ata/atapi-all.c +++ b/sys/dev/ata/atapi-all.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: atapi-all.c,v 1.5 1999/03/28 18:57:19 sos Exp $ + * $Id: atapi-all.c,v 1.6 1999/04/10 18:53:35 sos Exp $ */ #include "ata.h" @@ -310,13 +310,13 @@ printf("atapi_interrupt: length=%d reason=0x%02x\n", length, reason); printf("atapi_interrupt: write data underrun %d/%d\n", length, request->bytecount); outsw(atp->controller->ioaddr + ATA_DATA, - (void *)((int32_t)request->data), length / sizeof(int16_t)); + (void *)((uintptr_t)request->data), length / sizeof(int16_t)); for (resid=request->bytecount; resid<length; resid+=sizeof(int16_t)) outw(atp->controller->ioaddr + ATA_DATA, 0); } else { outsw(atp->controller->ioaddr + ATA_DATA, - (void *)((int32_t)request->data), length / sizeof(int16_t)); + (void *)((uintptr_t)request->data), length / sizeof(int16_t)); } request->bytecount -= length; request->data += length; @@ -331,13 +331,13 @@ printf("atapi_interrupt: length=%d reason=0x%02x\n", length, reason); printf("atapi_interrupt: read data overrun %d/%d\n", length, request->bytecount); insw(atp->controller->ioaddr + ATA_DATA, - (void *)((int32_t)request->data), length / sizeof(int16_t)); + (void *)((uintptr_t)request->data), length / sizeof(int16_t)); for (resid=request->bytecount; resid<length; resid+=sizeof(int16_t)) inw(atp->controller->ioaddr + ATA_DATA); } else { insw(atp->controller->ioaddr + ATA_DATA, - (void *)((int32_t)request->data), length / sizeof(int16_t)); + (void *)((uintptr_t)request->data), length / sizeof(int16_t)); } request->bytecount -= length; request->data += length; diff --git a/sys/dev/atkbdc/atkbd.c b/sys/dev/atkbdc/atkbd.c index f9e28febe12e..80c81a5968a6 100644 --- a/sys/dev/atkbdc/atkbd.c +++ b/sys/dev/atkbdc/atkbd.c @@ -23,7 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: atkbd.c,v 1.4 1999/01/28 10:55:55 yokota Exp $ + * $Id: atkbd.c,v 1.5 1999/03/10 10:36:52 yokota Exp $ */ #include "atkbd.h" @@ -46,7 +46,7 @@ #include <dev/kbd/atkbdreg.h> #include <dev/kbd/atkbdcreg.h> -#ifndef __i386__ +#if 1 #include <sys/bus.h> #include <isa/isareg.h> @@ -89,6 +89,7 @@ static struct cdevsw atkbd_cdevsw = { #endif /* KBD_INSTALL_CDEV */ +#if 0 #ifdef __i386__ atkbd_softc_t @@ -110,6 +111,7 @@ atkbd_softc_t } #endif /* __i386__ */ +#endif int atkbd_probe_unit(int unit, int port, int irq, int flags) @@ -376,16 +378,14 @@ atkbd_configure(int flags) { keyboard_t *kbd; int arg[2]; -#ifdef __i386__ - struct isa_device *dev; int i; /* XXX: a kludge to obtain the device configuration flags */ - dev = find_isadev(isa_devtab_tty, &atkbddriver, 0); - if (dev != NULL) { - flags |= dev->id_flags; + if (resource_int_value("atkbd", 0, "flags", &i) == 0) { + flags |= i; /* if the driver is disabled, unregister the keyboard if any */ - if (!dev->id_enabled) { + if (resource_int_value("atkbd", 0, "disabled", &i) == 0 + && i != 0) { i = kbd_find_keyboard(ATKBD_DRIVER_NAME, ATKBD_DEFAULT); if (i >= 0) { kbd = kbd_get_keyboard(i); @@ -395,8 +395,7 @@ atkbd_configure(int flags) } } } -#endif - + /* probe the keyboard controller */ atkbdc_configure(); diff --git a/sys/dev/atkbdc/atkbd_atkbdc.c b/sys/dev/atkbdc/atkbd_atkbdc.c index ade1ba088669..1d7ee623dd3b 100644 --- a/sys/dev/atkbdc/atkbd_atkbdc.c +++ b/sys/dev/atkbdc/atkbd_atkbdc.c @@ -23,7 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: atkbd_isa.c,v 1.1 1999/01/23 16:53:27 dfr Exp $ + * $Id: atkbd_isa.c,v 1.2 1999/03/10 10:36:49 yokota Exp $ */ #include "atkbd.h" @@ -37,6 +37,7 @@ #include <sys/conf.h> #include <sys/tty.h> #include <sys/bus.h> +#include <machine/bus.h> #include <sys/rman.h> #include <machine/resource.h> @@ -70,9 +71,9 @@ static driver_t atkbd_driver = { static int atkbdprobe(device_t dev) { - u_long port; - u_long irq; - u_long flags; + uintptr_t port; + uintptr_t irq; + uintptr_t flags; device_set_desc(dev, "AT Keyboard"); @@ -89,9 +90,9 @@ static int atkbdattach(device_t dev) { atkbd_softc_t *sc; - u_long port; - u_long irq; - u_long flags; + uintptr_t port; + uintptr_t irq; + uintptr_t flags; struct resource *res; void *ih; int zero = 0; diff --git a/sys/dev/atkbdc/atkbd_isa.c b/sys/dev/atkbdc/atkbd_isa.c index ade1ba088669..1d7ee623dd3b 100644 --- a/sys/dev/atkbdc/atkbd_isa.c +++ b/sys/dev/atkbdc/atkbd_isa.c @@ -23,7 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: atkbd_isa.c,v 1.1 1999/01/23 16:53:27 dfr Exp $ + * $Id: atkbd_isa.c,v 1.2 1999/03/10 10:36:49 yokota Exp $ */ #include "atkbd.h" @@ -37,6 +37,7 @@ #include <sys/conf.h> #include <sys/tty.h> #include <sys/bus.h> +#include <machine/bus.h> #include <sys/rman.h> #include <machine/resource.h> @@ -70,9 +71,9 @@ static driver_t atkbd_driver = { static int atkbdprobe(device_t dev) { - u_long port; - u_long irq; - u_long flags; + uintptr_t port; + uintptr_t irq; + uintptr_t flags; device_set_desc(dev, "AT Keyboard"); @@ -89,9 +90,9 @@ static int atkbdattach(device_t dev) { atkbd_softc_t *sc; - u_long port; - u_long irq; - u_long flags; + uintptr_t port; + uintptr_t irq; + uintptr_t flags; struct resource *res; void *ih; int zero = 0; diff --git a/sys/dev/atkbdc/psm.c b/sys/dev/atkbdc/psm.c index e7eb46957d1f..b3dc1d0583a2 100644 --- a/sys/dev/atkbdc/psm.c +++ b/sys/dev/atkbdc/psm.c @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: psm.c,v 1.2 1998/11/15 18:25:17 dfr Exp $ + * $Id: psm.c,v 1.3 1999/01/23 16:53:28 dfr Exp $ */ /* @@ -76,6 +76,7 @@ #include <sys/poll.h> #include <sys/syslog.h> #include <sys/malloc.h> +#include <machine/bus.h> #include <sys/rman.h> #ifdef DEVFS #include <sys/devfsext.h> @@ -740,8 +741,8 @@ psmprobe(device_t dev) { int unit = device_get_unit(dev); struct psm_softc *sc = device_get_softc(dev); - u_long port; - u_long flags; + uintptr_t port; + uintptr_t flags; int stat[3]; int command_byte; int mask; @@ -991,7 +992,7 @@ psmattach(device_t dev) struct psm_softc *sc = device_get_softc(dev); void *ih; struct resource *res; - u_long irq; + uintptr_t irq; int zero = 0; if (sc == NULL) /* shouldn't happen */ diff --git a/sys/dev/cs/if_cs.c b/sys/dev/cs/if_cs.c index 4a9c39093c98..f96f0248b9d3 100644 --- a/sys/dev/cs/if_cs.c +++ b/sys/dev/cs/if_cs.c @@ -27,7 +27,7 @@ */ /* - * $Id: if_cs.c,v 1.8 1999/01/12 00:27:43 eivind Exp $ + * $Id: if_cs.c,v 1.9 1999/01/28 01:59:53 dillon Exp $ * * Device driver for Crystal Semiconductor CS8920 based ethernet * adapters. By Maxim Bolotin and Oleg Sharoiko, 27-April-1997 @@ -1352,7 +1352,6 @@ cs_pnp_attach(u_long csn, u_long vend_id, char *name, int iobase, unit, flags; u_int irq; int drq; - struct isa_device *dvp; struct cs_softc *sc = malloc(sizeof *sc, M_DEVBUF, M_NOWAIT); if (read_pnp_parms ( &d , ldn ) == 0 ) { @@ -1373,9 +1372,7 @@ cs_pnp_attach(u_long csn, u_long vend_id, char *name, if (dev->id_driver == NULL) { dev->id_driver = &csdriver; - dvp = find_isadev(isa_devtab_net, &csdriver, 0); - if (dvp != NULL) - dev->id_id = dvp->id_id; + dev->id_id = isa_compat_nextid(); } if (!sc) return; diff --git a/sys/dev/ed/if_ed.c b/sys/dev/ed/if_ed.c index 1408b2b47327..29bb9d12fddf 100644 --- a/sys/dev/ed/if_ed.c +++ b/sys/dev/ed/if_ed.c @@ -24,7 +24,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: if_ed.c,v 1.149 1999/01/28 01:59:53 dillon Exp $ + * $Id: if_ed.c,v 1.150 1999/03/17 16:44:51 luigi Exp $ */ /* @@ -3488,7 +3488,6 @@ static void edpnp_attach(u_long csn, u_long vend_id, char *name, struct isa_device *dev) { struct pnp_cinfo d; - struct isa_device *dvp; if (dev->id_unit >= NEDTOT) return; @@ -3509,9 +3508,7 @@ edpnp_attach(u_long csn, u_long vend_id, char *name, struct isa_device *dev) if (dev->id_driver == NULL) { dev->id_driver = &eddriver; - dvp = find_isadev(isa_devtab_net, &eddriver, 0); - if (dvp != NULL) - dev->id_id = dvp->id_id; + dev->id_id = isa_compat_nextid(); } if ((dev->id_alive = ed_probe(dev)) != 0) diff --git a/sys/dev/fdc/fdc.c b/sys/dev/fdc/fdc.c index 07223f129697..0414b1868e1d 100644 --- a/sys/dev/fdc/fdc.c +++ b/sys/dev/fdc/fdc.c @@ -47,7 +47,7 @@ * SUCH DAMAGE. * * from: @(#)fd.c 7.4 (Berkeley) 5/25/91 - * $Id: fd.c,v 1.133 1999/02/10 00:03:32 ken Exp $ + * $Id: fd.c,v 1.134 1999/04/06 03:06:51 peter Exp $ * */ @@ -60,26 +60,37 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> +#include <sys/buf.h> +#include <sys/bus.h> #include <sys/conf.h> -#include <sys/fcntl.h> -#include <machine/clock.h> -#include <machine/ioctl_fd.h> #include <sys/disklabel.h> -#include <sys/buf.h> #include <sys/devicestat.h> +#include <sys/fcntl.h> #include <sys/malloc.h> +#include <sys/module.h> #include <sys/proc.h> #include <sys/syslog.h> -#include <i386/isa/isa.h> -#include <i386/isa/isa_device.h> -#include <i386/isa/fdreg.h> -#include <i386/isa/fdc.h> -#include <i386/isa/rtc.h> + +#include <sys/bus.h> +#include <machine/bus.h> +#include <sys/rman.h> + +#include <machine/clock.h> +#include <machine/ioctl_fd.h> +#include <machine/resource.h> #include <machine/stdarg.h> + #ifdef DEVFS #include <sys/devfsext.h> #endif /* DEVFS */ +#include <isa/isavar.h> +#include <i386/isa/isa.h> +#include <i386/isa/isa_dma.h> +#include <i386/isa/fdreg.h> +#include <i386/isa/fdc.h> +#include <i386/isa/rtc.h> + /* misuse a flag to identify format operation */ #define B_FORMAT B_XXX @@ -151,13 +162,13 @@ static struct fd_type fd_types[NUMTYPES] = /***********************************************************************\ * Per controller structure. * \***********************************************************************/ -struct fdc_data fdc_data[NFDC]; +static devclass_t fdc_devclass; /***********************************************************************\ * Per drive structure. * * N per controller (DRVS_PER_CTLR) * \***********************************************************************/ -static struct fd_data { +struct fd_data { struct fdc_data *fdc; /* pointer to controller structure */ int fdsu; /* this units number on this controller */ int type; /* Drive type (FD_1440...) */ @@ -179,7 +190,10 @@ static struct fd_data { void *bdevs[1 + NUMDENS + MAXPARTITIONS]; void *cdevs[1 + NUMDENS + MAXPARTITIONS]; #endif -} fd_data[NFD]; + device_t dev; + fdu_t fdu; +}; +static devclass_t fd_devclass; /***********************************************************************\ * Throughout this file the following conventions will be used: * @@ -195,29 +209,26 @@ static struct fd_data { static int yeattach(struct isa_device *); #endif -/* autoconfig functions */ -static int fdprobe(struct isa_device *); -static int fdattach(struct isa_device *); - /* needed for ft driver, thus exported */ -int in_fdc(fdcu_t); -int out_fdc(fdcu_t, int); +int in_fdc(struct fdc_data *); +int out_fdc(struct fdc_data *, int); /* internal functions */ -static void set_motor(fdcu_t, int, int); +static void fdc_add_device(device_t, const char *, int); +static void fdc_intr(void *); +static void set_motor(struct fdc_data *, int, int); # define TURNON 1 # define TURNOFF 0 static timeout_t fd_turnoff; static timeout_t fd_motor_on; -static void fd_turnon(fdu_t); +static void fd_turnon(struct fd_data *); static void fdc_reset(fdc_p); -static int fd_in(fdcu_t, int *); -static void fdstart(fdcu_t); +static int fd_in(struct fdc_data *, int *); +static void fdstart(struct fdc_data *); static timeout_t fd_iotimeout; static timeout_t fd_pseudointr; -static ointhand2_t fdintr; -static int fdstate(fdcu_t, fdc_p); -static int retrier(fdcu_t); +static int fdstate(struct fdc_data *); +static int retrier(struct fdc_data *); static int fdformat(dev_t, struct fd_formb *, struct proc *); static int enable_fifo(fdc_p fdc); @@ -356,13 +367,6 @@ static int yeintr(struct pccard_devinfo *devi) #endif /* NCARD > 0 */ #endif /* FDC_YE */ - -/* autoconfig structure */ - -struct isa_driver fdcdriver = { - fdprobe, fdattach, "fdc", -}; - static d_open_t Fdopen; /* NOTE, not fdopen */ static d_read_t fdread; static d_write_t fdwrite; @@ -374,28 +378,18 @@ static d_strategy_t fdstrategy; #define CDEV_MAJOR 9 #define BDEV_MAJOR 2 - -static struct cdevsw fd_cdevsw = { - Fdopen, fdclose, fdread, fdwrite, - fdioctl, nostop, nullreset, nodevtotty, - seltrue, nommap, fdstrategy, "fd", - NULL, -1, nodump, nopsize, - D_DISK, 0, -1 }; - - -static struct isa_device *fdcdevs[NFDC]; - - static int -fdc_err(fdcu_t fdcu, const char *s) +fdc_err(struct fdc_data *fdc, const char *s) { - fdc_data[fdcu].fdc_errs++; - if(s) { - if(fdc_data[fdcu].fdc_errs < FDC_ERRMAX) - printf("fdc%d: %s", fdcu, s); - else if(fdc_data[fdcu].fdc_errs == FDC_ERRMAX) - printf("fdc%d: too many errors, not logging any more\n", - fdcu); + fdc->fdc_errs++; + if (s) { + if (fdc->fdc_errs < FDC_ERRMAX) { + device_print_prettyname(fdc->fdc_dev); + printf("%s", s); + } else if (fdc->fdc_errs == FDC_ERRMAX) { + device_print_prettyname(fdc->fdc_dev); + printf("too many errors, not logging any more\n"); + } } return FD_FAILED; @@ -407,9 +401,8 @@ fdc_err(fdcu_t fdcu, const char *s) * # of output bytes, output bytes as ints ..., * # of input bytes, input bytes as ints ... */ - static int -fd_cmd(fdcu_t fdcu, int n_out, ...) +fd_cmd(struct fdc_data *fdc, int n_out, ...) { u_char cmd; int n_in; @@ -422,26 +415,26 @@ fd_cmd(fdcu_t fdcu, int n_out, ...) va_start(ap, n_out); for (n = 0; n < n_out; n++) { - if (out_fdc(fdcu, va_arg(ap, int)) < 0) + if (out_fdc(fdc, va_arg(ap, int)) < 0) { char msg[50]; snprintf(msg, sizeof(msg), "cmd %x failed at out byte %d of %d\n", cmd, n + 1, n_out); - return fdc_err(fdcu, msg); + return fdc_err(fdc, msg); } } n_in = va_arg(ap, int); for (n = 0; n < n_in; n++) { int *ptr = va_arg(ap, int *); - if (fd_in(fdcu, ptr) < 0) + if (fd_in(fdc, ptr) < 0) { char msg[50]; snprintf(msg, sizeof(msg), "cmd %02x failed at in byte %d of %d\n", cmd, n + 1, n_in); - return fdc_err(fdcu, msg); + return fdc_err(fdc, msg); } } @@ -462,8 +455,8 @@ enable_fifo(fdc_p fdc) * first byte, and check for an early turn of data directon. */ - if (out_fdc(fdc->fdcu, I8207X_CONFIGURE) < 0) - return fdc_err(fdc->fdcu, "Enable FIFO failed\n"); + if (out_fdc(fdc, I8207X_CONFIGURE) < 0) + return fdc_err(fdc, "Enable FIFO failed\n"); /* If command is invalid, return */ j = 100000; @@ -474,17 +467,17 @@ enable_fifo(fdc_p fdc) return FD_FAILED; } if (j<0 || - fd_cmd(fdc->fdcu, 3, + fd_cmd(fdc, 3, 0, (fifo_threshold - 1) & 0xf, 0, 0) < 0) { fdc_reset(fdc); - return fdc_err(fdc->fdcu, "Enable FIFO failed\n"); + return fdc_err(fdc, "Enable FIFO failed\n"); } fdc->flags |= FDC_HAS_FIFO; return 0; } - if (fd_cmd(fdc->fdcu, 4, + if (fd_cmd(fdc, 4, I8207X_CONFIGURE, 0, (fifo_threshold - 1) & 0xf, 0, 0) < 0) - return fdc_err(fdc->fdcu, "Re-enable FIFO failed\n"); + return fdc_err(fdc, "Re-enable FIFO failed\n"); return 0; } @@ -493,9 +486,9 @@ fd_sense_drive_status(fdc_p fdc, int *st3p) { int st3; - if (fd_cmd(fdc->fdcu, 2, NE7CMD_SENSED, fdc->fdu, 1, &st3)) + if (fd_cmd(fdc, 2, NE7CMD_SENSED, fdc->fdu, 1, &st3)) { - return fdc_err(fdc->fdcu, "Sense Drive Status failed\n"); + return fdc_err(fdc, "Sense Drive Status failed\n"); } if (st3p) *st3p = st3; @@ -506,13 +499,11 @@ fd_sense_drive_status(fdc_p fdc, int *st3p) static int fd_sense_int(fdc_p fdc, int *st0p, int *cylp) { - int st0, cyl; + int cyl, st0, ret; - int ret = fd_cmd(fdc->fdcu, 1, NE7CMD_SENSEI, 1, &st0); - - if (ret) - { - (void)fdc_err(fdc->fdcu, + ret = fd_cmd(fdc, 1, NE7CMD_SENSEI, 1, &st0); + if (ret) { + (void)fdc_err(fdc, "sense intr err reading stat reg 0\n"); return ret; } @@ -520,17 +511,15 @@ fd_sense_int(fdc_p fdc, int *st0p, int *cylp) if (st0p) *st0p = st0; - if ((st0 & NE7_ST0_IC) == NE7_ST0_IC_IV) - { + if ((st0 & NE7_ST0_IC) == NE7_ST0_IC_IV) { /* * There doesn't seem to have been an interrupt. */ return FD_NOT_VALID; } - if (fd_in(fdc->fdcu, &cyl) < 0) - { - return fdc_err(fdc->fdcu, "can't get cyl num\n"); + if (fd_in(fdc, &cyl) < 0) { + return fdc_err(fdc, "can't get cyl num\n"); } if (cylp) @@ -545,8 +534,7 @@ fd_read_status(fdc_p fdc, int fdsu) { int i, ret; - for (i = 0; i < 7; i++) - { + for (i = 0; i < 7; i++) { /* * XXX types are poorly chosen. Only bytes can by read * from the hardware, but fdc->status[] wants u_ints and @@ -554,7 +542,7 @@ fd_read_status(fdc_p fdc, int fdsu) */ int status; - ret = fd_in(fdc->fdcu, &status); + ret = fd_in(fdc, &status); fdc->status[i] = status; if (ret != 0) break; @@ -572,34 +560,92 @@ fd_read_status(fdc_p fdc, int fdsu) /* autoconfiguration stuff */ /****************************************************************************/ -/* - * probe for existance of controller - */ static int -fdprobe(struct isa_device *dev) +fdc_probe(device_t dev) { - fdcu_t fdcu = dev->id_unit; - if(fdc_data[fdcu].flags & FDC_ATTACHED) - { - printf("fdc%d: unit used multiple times\n", fdcu); - return 0; + int error, i, ic_type; + struct fdc_data *fdc; + char myname[8]; /* better be long enough */ + + fdc = device_get_softc(dev); + bzero(fdc, sizeof *fdc); + fdc->fdc_dev = dev; + fdc->rid_ioport = fdc->rid_irq = fdc->rid_drq = 0; + fdc->res_ioport = fdc->res_irq = fdc->res_drq = 0; + + fdc->res_ioport = bus_alloc_resource(dev, SYS_RES_IOPORT, + &fdc->rid_ioport, 0ul, ~0ul, + IO_FDCSIZE, RF_ACTIVE); + if (fdc->res_ioport == 0) { + device_print_prettyname(dev); + printf("cannot reserve I/O port range\n"); + error = ENXIO; + goto out; } - - fdcdevs[fdcu] = dev; - fdc_data[fdcu].baseport = dev->id_iobase; + fdc->baseport = fdc->res_ioport->r_start; + + fdc->res_irq = bus_alloc_resource(dev, SYS_RES_IRQ, + &fdc->rid_irq, 0ul, ~0ul, 1, + RF_ACTIVE); + if (fdc->res_irq == 0) { + device_print_prettyname(dev); + printf("cannot reserve interrupt line\n"); + error = ENXIO; + goto out; + } + fdc->res_drq = bus_alloc_resource(dev, SYS_RES_DRQ, + &fdc->rid_drq, 0ul, ~0ul, 1, + RF_ACTIVE); + if (fdc->res_drq == 0) { + device_print_prettyname(dev); + printf("cannot reserve DMA request line\n"); + error = ENXIO; + goto out; + } + fdc->dmachan = fdc->res_drq->r_start; + error = BUS_SETUP_INTR(device_get_parent(dev), dev, + fdc->res_irq, fdc_intr, fdc, &fdc->fdc_intr); /* First - lets reset the floppy controller */ - outb(dev->id_iobase+FDOUT, 0); + outb(fdc->baseport + FDOUT, 0); DELAY(100); - outb(dev->id_iobase+FDOUT, FDO_FRST); + outb(fdc->baseport + FDOUT, FDO_FRST); /* see if it can handle a command */ - if (fd_cmd(fdcu, - 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0), - 0)) - { - return(0); + if (fd_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240), + NE7_SPEC_2(2, 0), 0)) { + error = ENXIO; + goto out; + } + + if (fd_cmd(fdc, 1, NE7CMD_VERSION, 1, &ic_type) == 0) { + ic_type = (u_char)ic_type; + switch (ic_type) { + case 0x80: + device_set_desc(dev, "NEC 765 or clone"); + fdc->fdct = FDC_NE765; + break; + case 0x81: + device_set_desc(dev, "Intel 82077 or clone"); + fdc->fdct = FDC_I82077; + break; + case 0x90: + device_set_desc(dev, "NEC 72065B or clone"); + fdc->fdct = FDC_NE72065; + break; + default: + device_set_desc(dev, "generic floppy controller"); + fdc->fdct = FDC_UNKNOWN; + break; + } } + + snprintf(myname, sizeof(myname), "%s%d", device_get_name(dev), + device_get_unit(dev)); + for (i = resource_query_string(-1, "at", myname); i != -1; + i = resource_query_string(i, "at", myname)) + fdc_add_device(dev, resource_query_name(i), + resource_query_unit(i)); #ifdef FDC_YE /* * don't succeed on probe; wait @@ -608,277 +654,312 @@ fdprobe(struct isa_device *dev) if (dev->id_flags & FDC_IS_PCMCIA) return(0); #endif - return (IO_FDCSIZE); + return (0); + +out: + if (fdc->fdc_intr) + BUS_TEARDOWN_INTR(device_get_parent(dev), dev, fdc->res_irq, + fdc->fdc_intr); + if (fdc->res_irq != 0) { + bus_deactivate_resource(dev, SYS_RES_IRQ, fdc->rid_irq, + fdc->res_irq); + bus_release_resource(dev, SYS_RES_IRQ, fdc->rid_irq, + fdc->res_irq); + } + if (fdc->res_ioport != 0) { + bus_deactivate_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport, + fdc->res_ioport); + bus_release_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport, + fdc->res_ioport); + } + if (fdc->res_drq != 0) { + bus_deactivate_resource(dev, SYS_RES_DRQ, fdc->rid_drq, + fdc->res_drq); + bus_release_resource(dev, SYS_RES_DRQ, fdc->rid_drq, + fdc->res_drq); + } + return (error); } /* - * wire controller into system, look for floppy units + * Aped dfr@freebsd.org's isa_add_device(). */ +static void +fdc_add_device(device_t dev, const char *name, int unit) +{ + int disabled, *ivar; + device_t child; + + ivar = malloc(sizeof *ivar, M_DEVBUF /* XXX */, M_NOWAIT); + if (ivar == 0) + return; + if (resource_int_value(name, unit, "drive", ivar) == 0) + *ivar = 0; + child = device_add_child(dev, name, unit, ivar); + if (child == 0) + return; + if (resource_int_value(name, unit, "disabled", &disabled) == 0) + device_disable(child); +} + static int -fdattach(struct isa_device *dev) +fdc_attach(device_t dev) { - unsigned fdt; - fdu_t fdu; - fdcu_t fdcu = dev->id_unit; - fdc_p fdc = fdc_data + fdcu; - fd_p fd; - int fdsu, st0, st3, i; - struct isa_device *fdup; - int ic_type = 0; -#ifdef DEVFS - int mynor; - int typemynor; - int typesize; -#endif + struct fdc_data *fdc = device_get_softc(dev); + fdcu_t fdcu = device_get_unit(dev); - dev->id_ointr = fdintr; fdc->fdcu = fdcu; fdc->flags |= FDC_ATTACHED; - fdc->dmachan = dev->id_drq; + /* 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 */ outb(fdc->baseport + FDOUT, ((fdc->fdout = 0))); bufq_init(&fdc->head); - /* check for each floppy drive */ - for (fdup = isa_biotab_fdc; fdup->id_driver != 0; fdup++) { - if (fdup->id_iobase != dev->id_iobase) - continue; - fdu = fdup->id_unit; - fd = &fd_data[fdu]; - if (fdu >= (NFD)) - continue; - fdsu = fdup->id_physid; - /* look up what bios thinks we have */ - switch (fdu) { - case 0: if (dev->id_flags & FDC_PRETEND_D0) - fdt = RTCFDT_144M | RTCFDT_144M_PRETENDED; - else - fdt = (rtcin(RTC_FDISKETTE) & 0xf0); - break; - case 1: fdt = ((rtcin(RTC_FDISKETTE) << 4) & 0xf0); - break; - default: fdt = RTCFDT_NONE; - break; - } - /* is there a unit? */ - if ((fdt == RTCFDT_NONE) - ) { - fd->type = NO_TYPE; - continue; - } +#ifdef FIFO_BEFORE_MOTORON + /* Hmm, this doesn't work here - is set_motor() magic? -Peter */ + if (fdc->fdct != FDC_NE765 && fdc->fdct != FDC_UNKNOWN + && enable_fifo(fdc) == 0) { + device_print_prettyname(dev); + printf("FIFO enabled, %d bytes threshold\n", fifo_threshold); + } +#endif + /* + * Probe and attach any children as were configured above. + */ + return (bus_generic_attach(dev)); +} - /* select it */ - set_motor(fdcu, fdsu, TURNON); - DELAY(1000000); /* 1 sec */ +static void +fdc_print_child(device_t me, device_t child) +{ + printf(" at %s%d drive %d", device_get_name(me), device_get_unit(me), + *(int *)device_get_ivars(child)); +} - if (ic_type == 0 && - fd_cmd(fdcu, 1, NE7CMD_VERSION, 1, &ic_type) == 0) - { -#ifdef FDC_PRINT_BOGUS_CHIPTYPE - printf("fdc%d: ", fdcu); -#endif - ic_type = (u_char)ic_type; - switch( ic_type ) { - case 0x80: -#ifdef FDC_PRINT_BOGUS_CHIPTYPE - printf("NEC 765\n"); -#endif - fdc->fdct = FDC_NE765; - break; - case 0x81: -#ifdef FDC_PRINT_BOGUS_CHIPTYPE - printf("Intel 82077\n"); -#endif - fdc->fdct = FDC_I82077; - break; - case 0x90: -#ifdef FDC_PRINT_BOGUS_CHIPTYPE - printf("NEC 72065B\n"); +static int +fd_probe(device_t dev) +{ + int i; + u_int fdt, st0, st3; + struct fd_data *fd; + struct fdc_data *fdc; + fdsu_t fdsu; +#ifndef FIFO_BEFORE_MOTORON + static int fd_fifo = 0; #endif - fdc->fdct = FDC_NE72065; - break; - default: -#ifdef FDC_PRINT_BOGUS_CHIPTYPE - printf("unknown IC type %02x\n", ic_type); + + fdsu = *(int *)device_get_ivars(dev); /* xxx cheat a bit... */ + fd = device_get_softc(dev); + fdc = device_get_softc(device_get_parent(dev)); + + bzero(fd, sizeof *fd); + fd->dev = dev; + fd->fdc = fdc; + fd->fdsu = fdsu; + fd->fdu = device_get_unit(dev); + + /* look up what bios thinks we have */ + switch (fd->fdu) { + case 0: + if (isa_get_flags(fdc->fdc_dev) & FDC_PRETEND_D0) + fdt = RTCFDT_144M | RTCFDT_144M_PRETENDED; + else + fdt = (rtcin(RTC_FDISKETTE) & 0xf0); + break; + case 1: + fdt = ((rtcin(RTC_FDISKETTE) << 4) & 0xf0); + break; + default: + fdt = RTCFDT_NONE; + break; + } + + /* is there a unit? */ + if (fdt == RTCFDT_NONE) + return (ENXIO); + + /* select it */ + set_motor(fdc, fdsu, TURNON); + DELAY(1000000); /* 1 sec */ + +#ifndef FIFO_BEFORE_MOTORON + if (fd_fifo == 0 && fdc->fdct != FDC_NE765 && fdc->fdct != FDC_UNKNOWN + && enable_fifo(fdc) == 0) { + device_print_prettyname(device_get_parent(dev)); + printf("FIFO enabled, %d bytes threshold\n", fifo_threshold); + } + fd_fifo = 1; #endif - fdc->fdct = FDC_UNKNOWN; - break; - } - if (fdc->fdct != FDC_NE765 && - fdc->fdct != FDC_UNKNOWN && - enable_fifo(fdc) == 0) { - printf("fdc%d: FIFO enabled", fdcu); - printf(", %d bytes threshold\n", - fifo_threshold); - } - } - 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); - } + if ((fd_cmd(fdc, 2, NE7CMD_SENSED, fdsu, 1, &st3) == 0) + && (st3 & NE7_ST3_T0)) { + /* if at track 0, first seek inwards */ + /* seek some steps: */ + fd_cmd(fdc, 3, NE7CMD_SEEK, fdsu, 10, 0); + DELAY(300000); /* ...wait a moment... */ + 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(fdc, 3, NE7CMD_SEEK, fdsu, 10, 0) == 0) { + /* ...wait a moment... */ + DELAY(300000); + /* make ctrlr happy: */ + 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); + 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(fdc, 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 */ - } + /* anything responding? */ + if (fd_sense_int(fdc, &st0, 0) == 0 && + (st0 & NE7_ST0_EC) == 0) + break; /* already probed succesfully */ } + } - set_motor(fdcu, fdsu, TURNOFF); + set_motor(fdc, fdsu, TURNOFF); - if (st0 & NE7_ST0_EC) /* no track 0 -> no drive present */ - continue; + if (st0 & NE7_ST0_EC) /* no track 0 -> no drive present */ + return (ENXIO); - fd->track = FD_NO_TRACK; - fd->fdc = fdc; - fd->fdsu = fdsu; - fd->options = 0; - callout_handle_init(&fd->toffhandle); - callout_handle_init(&fd->tohandle); - printf("fd%d: ", fdu); - - switch (fdt) { - case RTCFDT_12M: - printf("1.2MB 5.25in\n"); - fd->type = FD_1200; - break; - case RTCFDT_144M | RTCFDT_144M_PRETENDED: - printf("config-pretended "); - fdt = RTCFDT_144M; - /* fallthrough */ - case RTCFDT_144M: - printf("1.44MB 3.5in\n"); - fd->type = FD_1440; + fd->track = FD_NO_TRACK; + fd->fdc = fdc; + fd->fdsu = fdsu; + fd->options = 0; + callout_handle_init(&fd->toffhandle); + callout_handle_init(&fd->tohandle); + + switch (fdt) { + case RTCFDT_12M: + device_set_desc(dev, "1200-KB 5.25\" drive"); + fd->type = FD_1200; + break; + case RTCFDT_144M | RTCFDT_144M_PRETENDED: + device_set_desc(dev, "config-pretended 1440-MB 3.5\" drive"); + fdt = RTCFDT_144M; + fd->type = FD_1440; + case RTCFDT_144M: + device_set_desc(dev, "1440-KB 3.5\" drive"); + fd->type = FD_1440; + break; + case RTCFDT_288M: + case RTCFDT_288M_1: + device_set_desc(dev, "2880-KB 3.5\" drive (in 1440-KB mode)"); + fd->type = FD_1440; + break; + case RTCFDT_360K: + device_set_desc(dev, "360-KB 5.25\" drive"); + fd->type = FD_360; + break; + case RTCFDT_720K: + printf("720-KB 3.5\" drive"); + fd->type = FD_720; + break; + default: + return (ENXIO); + } + return (0); +} + +static int +fd_attach(device_t dev) +{ + struct fd_data *fd; + + fd = device_get_softc(dev); + +#ifdef DEVFS /* XXX bitrot */ + mynor = fdu << 6; + fd->bdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_BLK, + UID_ROOT, GID_OPERATOR, 0640, + "fd%d", fdu); + fd->cdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_CHR, + UID_ROOT, GID_OPERATOR, 0640, + "rfd%d", fdu); + for (i = 1; i < 1 + NUMDENS; i++) { + /* + * XXX this and the lookup in Fdopen() should be + * data driven. + */ + switch (fd->type) { + case FD_360: + if (i != FD_360) + continue; break; - case RTCFDT_288M: - case RTCFDT_288M_1: - printf("2.88MB 3.5in - 1.44MB mode\n"); - fd->type = FD_1440; + case FD_720: + if (i != FD_720 && i != FD_800 && i != FD_820) + continue; break; - case RTCFDT_360K: - printf("360KB 5.25in\n"); - fd->type = FD_360; + case FD_1200: + if (i != FD_360 && i != FD_720 && i != FD_800 + && i != FD_820 && i != FD_1200 + && i != FD_1440 && i != FD_1480) + continue; break; - case RTCFDT_720K: - printf("720KB 3.5in\n"); - fd->type = FD_720; + case FD_1440: + if (i != FD_720 && i != FD_800 && i != FD_820 + && i != FD_1200 && i != FD_1440 + && i != FD_1480 && i != FD_1720) + continue; break; - default: - printf("unknown\n"); - fd->type = NO_TYPE; - continue; } -#ifdef DEVFS - mynor = fdu << 6; - fd->bdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_BLK, - UID_ROOT, GID_OPERATOR, 0640, - "fd%d", fdu); - fd->cdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_CHR, - UID_ROOT, GID_OPERATOR, 0640, - "rfd%d", fdu); - for (i = 1; i < 1 + NUMDENS; i++) { - /* - * XXX this and the lookup in Fdopen() should be - * data driven. - */ - switch (fd->type) { - case FD_360: - if (i != FD_360) - continue; - break; - case FD_720: - if (i != FD_720 && i != FD_800 && i != FD_820) - continue; - break; - case FD_1200: - if (i != FD_360 && i != FD_720 && i != FD_800 - && i != FD_820 && i != FD_1200 - && i != FD_1440 && i != FD_1480) - continue; - break; - case FD_1440: - if (i != FD_720 && i != FD_800 && i != FD_820 - && i != FD_1200 && i != FD_1440 - && i != FD_1480 && i != FD_1720) - continue; - break; - } - typesize = fd_types[i - 1].size / 2; - /* - * XXX all these conversions give bloated code and - * confusing names. - */ - if (typesize == 1476) - typesize = 1480; - if (typesize == 1722) - typesize = 1720; - typemynor = mynor | i; - fd->bdevs[i] = - devfs_add_devswf(&fd_cdevsw, typemynor, DV_BLK, - UID_ROOT, GID_OPERATOR, 0640, - "fd%d.%d", fdu, typesize); - fd->cdevs[i] = - devfs_add_devswf(&fd_cdevsw, typemynor, DV_CHR, - UID_ROOT, GID_OPERATOR, 0640, - "rfd%d.%d", fdu, typesize); - } - - for (i = 0; i < MAXPARTITIONS; i++) { - fd->bdevs[1 + NUMDENS + i] = devfs_makelink(fd->bdevs[0], - "fd%d%c", fdu, 'a' + i); - fd->cdevs[1 + NUMDENS + i] = - devfs_makelink(fd->cdevs[0], - "rfd%d%c", fdu, 'a' + i); - } -#endif /* DEVFS */ + typesize = fd_types[i - 1].size / 2; /* - * Export the drive to the devstat interface. + * XXX all these conversions give bloated code and + * confusing names. */ - devstat_add_entry(&fd->device_stats, "fd", - fdu, 512, - DEVSTAT_NO_ORDERED_TAGS, - DEVSTAT_TYPE_FLOPPY | DEVSTAT_TYPE_IF_OTHER, - DEVSTAT_PRIORITY_FD); - + if (typesize == 1476) + typesize = 1480; + if (typesize == 1722) + typesize = 1720; + typemynor = mynor | i; + fd->bdevs[i] = + devfs_add_devswf(&fd_cdevsw, typemynor, DV_BLK, + UID_ROOT, GID_OPERATOR, 0640, + "fd%d.%d", fdu, typesize); + fd->cdevs[i] = + devfs_add_devswf(&fd_cdevsw, typemynor, DV_CHR, + UID_ROOT, GID_OPERATOR, 0640, + "rfd%d.%d", fdu, typesize); } - return (1); + for (i = 0; i < MAXPARTITIONS; i++) { + fd->bdevs[1 + NUMDENS + i] = devfs_makelink(fd->bdevs[0], + "fd%d%c", fdu, 'a' + i); + fd->cdevs[1 + NUMDENS + i] = + devfs_makelink(fd->cdevs[0], + "rfd%d%c", fdu, 'a' + i); + } +#endif /* DEVFS */ + /* + * Export the drive to the devstat interface. + */ + devstat_add_entry(&fd->device_stats, device_get_name(dev), + device_get_unit(dev), 512, DEVSTAT_NO_ORDERED_TAGS, + DEVSTAT_TYPE_FLOPPY | DEVSTAT_TYPE_IF_OTHER, + DEVSTAT_PRIORITY_FD); + return (0); } - - #ifdef FDC_YE /* * this is a subset of fdattach() optimized for the Y-E Data @@ -1016,9 +1097,9 @@ static int yeattach(struct isa_device *dev) /* remember to not deselect the drive we're working on */ /****************************************************************************/ static void -set_motor(fdcu_t fdcu, int fdsu, int turnon) +set_motor(struct fdc_data *fdc, int fdsu, int turnon) { - int fdout = fdc_data[fdcu].fdout; + int fdout = fdc->fdout; int needspecify = 0; if(turnon) { @@ -1038,83 +1119,78 @@ set_motor(fdcu_t fdcu, int fdsu, int turnon) fdout |= (FDO_FRST|FDO_FDMAEN); } - outb(fdc_data[fdcu].baseport+FDOUT, fdout); - fdc_data[fdcu].fdout = fdout; + outb(fdc->baseport+FDOUT, fdout); + fdc->fdout = fdout; TRACE1("[0x%x->FDOUT]", fdout); - if(needspecify) { + if (needspecify) { /* * XXX * special case: since we have just woken up the FDC * from its sleep, we silently assume the command will * be accepted, and do not test for a timeout */ - (void)fd_cmd(fdcu, 3, NE7CMD_SPECIFY, + (void)fd_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0), 0); - if (fdc_data[fdcu].flags & FDC_HAS_FIFO) - (void) enable_fifo(&fdc_data[fdcu]); + if (fdc->flags & FDC_HAS_FIFO) + (void) enable_fifo(fdc); } } static void -fd_turnoff(void *arg1) +fd_turnoff(void *xfd) { - fdu_t fdu = (fdu_t)arg1; int s; - fd_p fd = fd_data + fdu; + fd_p fd = xfd; - TRACE1("[fd%d: turnoff]", fdu); + 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 == fdu) { - fd->toffhandle = timeout(fd_turnoff, arg1, 4 * hz); + 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->fdcu, fd->fdsu, TURNOFF); + set_motor(fd->fdc, fd->fdsu, TURNOFF); splx(s); } static void -fd_motor_on(void *arg1) +fd_motor_on(void *xfd) { - fdu_t fdu = (fdu_t)arg1; int s; + fd_p fd = xfd; - fd_p fd = fd_data + fdu; s = splbio(); fd->flags &= ~FD_MOTOR_WAIT; if((fd->fdc->fd == fd) && (fd->fdc->state == MOTORWAIT)) { - fdintr(fd->fdc->fdcu); + fdc_intr(fd->fdc); } splx(s); } static void -fd_turnon(fdu_t fdu) +fd_turnon(fd_p fd) { - fd_p fd = fd_data + fdu; if(!(fd->flags & FD_MOTOR)) { fd->flags |= (FD_MOTOR + FD_MOTOR_WAIT); - set_motor(fd->fdc->fdcu, fd->fdsu, TURNON); - timeout(fd_motor_on, (caddr_t)fdu, hz); /* in 1 sec its ok */ + set_motor(fd->fdc, fd->fdsu, TURNON); + timeout(fd_motor_on, fd, hz); /* in 1 sec its ok */ } } static void fdc_reset(fdc_p fdc) { - fdcu_t fdcu = fdc->fdcu; - /* Try a reset, keep motor on */ outb(fdc->baseport + FDOUT, fdc->fdout & ~(FDO_FRST|FDO_FDMAEN)); TRACE1("[0x%x->FDOUT]", fdc->fdout & ~(FDO_FRST|FDO_FDMAEN)); @@ -1127,7 +1203,7 @@ fdc_reset(fdc_p fdc) TRACE1("[0x%x->FDOUT]", fdc->fdout); /* XXX after a reset, silently believe the FDC will accept commands */ - (void)fd_cmd(fdcu, 3, NE7CMD_SPECIFY, + (void)fd_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0), 0); if (fdc->flags & FDC_HAS_FIFO) @@ -1138,16 +1214,16 @@ fdc_reset(fdc_p fdc) /* fdc in/out */ /****************************************************************************/ int -in_fdc(fdcu_t fdcu) +in_fdc(struct fdc_data *fdc) { - int baseport = fdc_data[fdcu].baseport; + int baseport = fdc->baseport; int i, j = 100000; while ((i = inb(baseport+FDSTS) & (NE7_DIO|NE7_RQM)) != (NE7_DIO|NE7_RQM) && j-- > 0) if (i == NE7_RQM) - return fdc_err(fdcu, "ready for output in input\n"); + return fdc_err(fdc, "ready for output in input\n"); if (j <= 0) - return fdc_err(fdcu, bootverbose? "input ready timeout\n": 0); + return fdc_err(fdc, bootverbose? "input ready timeout\n": 0); #ifdef FDC_DEBUG i = inb(baseport+FDDATA); TRACE1("[FDDATA->0x%x]", (unsigned char)i); @@ -1161,16 +1237,16 @@ in_fdc(fdcu_t fdcu) * fd_in: Like in_fdc, but allows you to see if it worked. */ static int -fd_in(fdcu_t fdcu, int *ptr) +fd_in(struct fdc_data *fdc, int *ptr) { - int baseport = fdc_data[fdcu].baseport; + int baseport = fdc->baseport; int i, j = 100000; while ((i = inb(baseport+FDSTS) & (NE7_DIO|NE7_RQM)) != (NE7_DIO|NE7_RQM) && j-- > 0) if (i == NE7_RQM) - return fdc_err(fdcu, "ready for output in input\n"); + return fdc_err(fdc, "ready for output in input\n"); if (j <= 0) - return fdc_err(fdcu, bootverbose? "input ready timeout\n": 0); + return fdc_err(fdc, bootverbose? "input ready timeout\n": 0); #ifdef FDC_DEBUG i = inb(baseport+FDDATA); TRACE1("[FDDATA->0x%x]", (unsigned char)i); @@ -1185,21 +1261,21 @@ fd_in(fdcu_t fdcu, int *ptr) } int -out_fdc(fdcu_t fdcu, int x) +out_fdc(struct fdc_data *fdc, int x) { - int baseport = fdc_data[fdcu].baseport; + int baseport = fdc->baseport; int i; /* Check that the direction bit is set */ i = 100000; while ((inb(baseport+FDSTS) & NE7_DIO) && i-- > 0); - if (i <= 0) return fdc_err(fdcu, "direction bit not set\n"); + if (i <= 0) return fdc_err(fdc, "direction bit not set\n"); /* Check that the floppy controller is ready for a command */ i = 100000; while ((inb(baseport+FDSTS) & NE7_RQM) == 0 && i-- > 0); if (i <= 0) - return fdc_err(fdcu, bootverbose? "output ready timeout\n": 0); + return fdc_err(fdc, bootverbose? "output ready timeout\n": 0); /* Send the command and return */ outb(baseport+FDDATA, x); @@ -1215,32 +1291,33 @@ Fdopen(dev_t dev, int flags, int mode, struct proc *p) { fdu_t fdu = FDUNIT(minor(dev)); int type = FDTYPE(minor(dev)); + fd_p fd; fdc_p fdc; /* check bounds */ - if (fdu >= NFD) - return(ENXIO); - fdc = fd_data[fdu].fdc; - if ((fdc == NULL) || (fd_data[fdu].type == NO_TYPE)) - return(ENXIO); + if ((fd = devclass_get_softc(fd_devclass, fdu)) == 0) + return (ENXIO); + fdc = fd->fdc; + if ((fdc == NULL) || (fd->type == NO_TYPE)) + return (ENXIO); if (type > NUMDENS) - return(ENXIO); + return (ENXIO); if (type == 0) - type = fd_data[fdu].type; + type = fd->type; else { /* * For each type of basic drive, make sure we are trying * to open a type it can do, */ - if (type != fd_data[fdu].type) { - switch (fd_data[fdu].type) { + if (type != fd->type) { + switch (fd->type) { case FD_360: - return(ENXIO); + return (ENXIO); case FD_720: if ( type != FD_820 && type != FD_800 ) - return(ENXIO); + return (ENXIO); break; case FD_1200: switch (type) { @@ -1279,9 +1356,10 @@ Fdopen(dev_t dev, int flags, int mode, struct proc *p) } } } - fd_data[fdu].ft = fd_types + type - 1; - fd_data[fdu].flags |= FD_OPEN; - + fd->ft = fd_types + type - 1; + fd->flags |= FD_OPEN; + device_busy(fd->dev); + device_busy(fd->fdc->fdc_dev); return 0; } @@ -1289,11 +1367,13 @@ int fdclose(dev_t dev, int flags, int mode, struct proc *p) { fdu_t fdu = FDUNIT(minor(dev)); + struct fd_data *fd; - fd_data[fdu].flags &= ~FD_OPEN; - fd_data[fdu].options &= ~FDOPT_NORETRY; + fd = devclass_get_softc(fd_devclass, fdu); + fd->flags &= ~FD_OPEN; + fd->options &= ~FDOPT_NORETRY; - return(0); + return (0); } static int @@ -1317,16 +1397,17 @@ fdstrategy(struct buf *bp) { unsigned nblocks, blknum, cando; int s; - fdcu_t fdcu; fdu_t fdu; fdc_p fdc; fd_p fd; size_t fdblk; fdu = FDUNIT(minor(bp->b_dev)); - fd = &fd_data[fdu]; + fd = devclass_get_softc(fd_devclass, fdu); + if (fd == 0) + panic("fdstrategy: buf for nonexistent device (%#lx, %#lx)", + (u_long)major(bp->b_dev), (u_long)minor(bp->b_dev)); fdc = fd->fdc; - fdcu = fdc->fdcu; #ifdef FDC_YE if (fd->type == NO_TYPE) { bp->b_error = ENXIO; @@ -1341,7 +1422,7 @@ fdstrategy(struct buf *bp) fdblk = 128 << (fd->ft->secsize); if (!(bp->b_flags & B_FORMAT)) { - if ((fdu >= NFD) || (bp->b_blkno < 0)) { + if (bp->b_blkno < 0) { printf( "fd%d: fdstrat: bad request blkno = %lu, bcount = %ld\n", fdu, (u_long)bp->b_blkno, bp->b_bcount); @@ -1386,12 +1467,12 @@ fdstrategy(struct buf *bp) bp->b_pblkno = bp->b_blkno; s = splbio(); bufqdisksort(&fdc->head, bp); - untimeout(fd_turnoff, (caddr_t)fdu, fd->toffhandle); /* a good idea */ + untimeout(fd_turnoff, fd, fd->toffhandle); /* a good idea */ /* Tell devstat we are starting on the transaction */ devstat_start_transaction(&fd->device_stats); - fdstart(fdcu); + fdstart(fdc); splx(s); return; @@ -1409,27 +1490,25 @@ bad: * will pick up our work when the present work completes * \***************************************************************/ static void -fdstart(fdcu_t fdcu) +fdstart(struct fdc_data *fdc) { int s; s = splbio(); - if(fdc_data[fdcu].state == DEVIDLE) + if(fdc->state == DEVIDLE) { - fdintr(fdcu); + fdc_intr(fdc); } splx(s); } static void -fd_iotimeout(void *arg1) +fd_iotimeout(void *xfdc) { fdc_p fdc; - fdcu_t fdcu; int s; - fdcu = (fdcu_t)arg1; - fdc = fdc_data + fdcu; + fdc = xfdc; TRACE1("fd%d[fd_iotimeout()]", fdc->fdu); /* @@ -1447,19 +1526,18 @@ fd_iotimeout(void *arg1) fdc->status[0] = NE7_ST0_IC_IV; fdc->flags &= ~FDC_STAT_VALID; fdc->state = IOTIMEDOUT; - fdintr(fdcu); + fdc_intr(fdc); splx(s); } /* just ensure it has the right spl */ static void -fd_pseudointr(void *arg1) +fd_pseudointr(void *xfdc) { - fdcu_t fdcu = (fdcu_t)arg1; int s; s = splbio(); - fdintr(fdcu); + fdc_intr(xfdc); splx(s); } @@ -1469,11 +1547,11 @@ fd_pseudointr(void *arg1) * ALWAYS called at SPLBIO * \***********************************************************************/ static void -fdintr(fdcu_t fdcu) +fdc_intr(void *xfdc) { - fdc_p fdc = fdc_data + fdcu; - while(fdstate(fdcu, fdc)) - ; + fdc_p fdc = xfdc; + while(fdstate(fdc)) + ; } #ifdef FDC_YE @@ -1513,7 +1591,7 @@ static int fdcpio(fdcu_t fdcu, long flags, caddr_t addr, u_int count) * if it returns a non zero value, it should be called again immediatly * \***********************************************************************/ static int -fdstate(fdcu_t fdcu, fdc_p fdc) +fdstate(fdc_p fdc) { int read, format, head, i, sec = 0, sectrac, st0, cyl, st3; unsigned blknum = 0, b_cylinder = 0; @@ -1537,26 +1615,25 @@ fdstate(fdcu_t fdcu, fdc_p fdc) * Force into the IDLE state, * \***********************************************/ fdc->state = DEVIDLE; - if(fdc->fd) - { - printf("fd%d: unexpected valid fd pointer\n", - fdc->fdu); + if (fdc->fd) { + device_print_prettyname(fdc->fdc_dev); + printf("unexpected valid fd pointer\n"); fdc->fd = (fd_p) 0; fdc->fdu = -1; } - TRACE1("[fdc%d IDLE]", fdcu); - return(0); + TRACE1("[fdc%d IDLE]", fdc->fdcu); + return (0); } fdu = FDUNIT(minor(bp->b_dev)); - fd = fd_data + fdu; + fd = devclass_get_softc(fd_devclass, fdu); fdblk = 128 << fd->ft->secsize; - if (fdc->fd && (fd != fdc->fd)) - { - printf("fd%d: confused fd pointers\n", fdu); + if (fdc->fd && (fd != fdc->fd)) { + device_print_prettyname(fd->dev); + printf("confused fd pointers\n"); } read = bp->b_flags & B_READ; format = bp->b_flags & B_FORMAT; - if(format) { + if (format) { finfo = (struct fd_formb *)bp->b_data; fd->skip = (char *)&(finfo->fd_formb_cylno(0)) - (char *)finfo; @@ -1569,8 +1646,8 @@ fdstate(fdcu_t fdcu, fdc_p fdc) TRACE1("fd%d", fdu); TRACE1("[%s]", fdstates[fdc->state]); TRACE1("(0x%x)", fd->flags); - untimeout(fd_turnoff, (caddr_t)fdu, fd->toffhandle); - fd->toffhandle = timeout(fd_turnoff, (caddr_t)fdu, 4 * hz); + untimeout(fd_turnoff, fd, fd->toffhandle); + fd->toffhandle = timeout(fd_turnoff, fd, 4 * hz); switch (fdc->state) { case DEVIDLE: @@ -1585,10 +1662,9 @@ fdstate(fdcu_t fdcu, fdc_p fdc) * If the next drive has a motor startup pending, then * * it will start up in its own good time * \*******************************************************/ - if(fd->flags & FD_MOTOR_WAIT) - { + if(fd->flags & FD_MOTOR_WAIT) { fdc->state = MOTORWAIT; - return(0); /* come back later */ + return (0); /* come back later */ } /*******************************************************\ * Maybe if it's not starting, it SHOULD be starting * @@ -1596,12 +1672,12 @@ fdstate(fdcu_t fdcu, fdc_p fdc) if (!(fd->flags & FD_MOTOR)) { fdc->state = MOTORWAIT; - fd_turnon(fdu); - return(0); + fd_turnon(fd); + return (0); } else /* at least make sure we are selected */ { - set_motor(fdcu, fd->fdsu, TURNON); + set_motor(fdc, fd->fdsu, TURNON); } if (fdc->flags & FDC_NEEDS_RESET) { fdc->state = RESETCTLR; @@ -1615,7 +1691,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc) fdc->state = SEEKCOMPLETE; break; } - if (fd_cmd(fdcu, 3, NE7CMD_SEEK, + if (fd_cmd(fdc, 3, NE7CMD_SEEK, fd->fdsu, b_cylinder * fd->ft->steptrac, 0)) { @@ -1624,20 +1700,19 @@ fdstate(fdcu_t fdcu, fdc_p fdc) * the FDC went off to the Saints... */ fdc->retry = 6; /* try a reset */ - return(retrier(fdcu)); + return(retrier(fdc)); } fd->track = FD_NO_TRACK; fdc->state = SEEKWAIT; return(0); /* will return later */ case SEEKWAIT: /* allow heads to settle */ - timeout(fd_pseudointr, (caddr_t)fdcu, hz / 16); + timeout(fd_pseudointr, fdc, hz / 16); fdc->state = SEEKCOMPLETE; return(0); /* will return later */ case SEEKCOMPLETE : /* SEEK DONE, START DMA */ /* Make sure seek really happened*/ - if(fd->track == FD_NO_TRACK) - { + if(fd->track == FD_NO_TRACK) { int descyl = b_cylinder * fd->ft->steptrac; do { /* @@ -1669,8 +1744,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc) return 0; /* hope for a real intr */ } while ((st0 & NE7_ST0_IC) == NE7_ST0_IC_RC); - if (0 == descyl) - { + if (0 == descyl) { int failed = 0; /* * seek to cyl 0 requested; make sure we are @@ -1685,22 +1759,20 @@ fdstate(fdcu_t fdcu, fdc_p fdc) failed = 1; } - if (failed) - { + if (failed) { if(fdc->retry < 3) fdc->retry = 3; - return(retrier(fdcu)); + return (retrier(fdc)); } } - if (cyl != descyl) - { + if (cyl != descyl) { printf( "fd%d: Seek to cyl %d failed; am at cyl %d (ST0 = 0x%x)\n", fdu, descyl, cyl, st0); if (fdc->retry < 3) fdc->retry = 3; - return(retrier(fdcu)); + return (retrier(fdc)); } } @@ -1726,7 +1798,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc) format ? bp->b_bcount : fdblk, fdc->dmachan); fdc->retry = 6; /* reset the beast */ - return(retrier(fdcu)); + return (retrier(fdc)); } if(st3 & NE7_ST3_WP) { @@ -1749,8 +1821,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc) } } - if(format) - { + if (format) { #ifdef FDC_YE if (fdc->flags & FDC_PCMCIA) (void)fdcpio(fdcu,bp->b_flags, @@ -1758,25 +1829,19 @@ fdstate(fdcu_t fdcu, fdc_p fdc) bp->b_bcount); #endif /* formatting */ - if(fd_cmd(fdcu, 6, - NE7CMD_FORMAT, - head << 2 | fdu, + if(fd_cmd(fdc, 6, NE7CMD_FORMAT, head << 2 | fdu, finfo->fd_formb_secshift, finfo->fd_formb_nsecs, finfo->fd_formb_gaplen, - finfo->fd_formb_fillbyte, - 0)) - { + 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(fdcu)); + return (retrier(fdc)); } - } - else - { + } else { #ifdef FDC_YE if (fdc->flags & FDC_PCMCIA) { /* @@ -1795,7 +1860,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc) fdblk); } #endif - if (fd_cmd(fdcu, 9, + if (fd_cmd(fdc, 9, (read ? NE7CMD_READ : NE7CMD_WRITE), head << 2 | fdu, /* head & unit */ fd->track, /* track */ @@ -1805,14 +1870,13 @@ fdstate(fdcu_t fdcu, fdc_p fdc) sectrac, /* sectors/track */ fd->ft->gap, /* gap size */ fd->ft->datalen, /* data length */ - 0)) - { + 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(fdcu)); + return (retrier(fdc)); } } #ifdef FDC_YE @@ -1834,8 +1898,8 @@ fdstate(fdcu_t fdcu, fdc_p fdc) */ #endif fdc->state = IOCOMPLETE; - fd->tohandle = timeout(fd_iotimeout, (caddr_t)fdcu, hz); - return(0); /* will return later */ + fd->tohandle = timeout(fd_iotimeout, fdc, hz); + return (0); /* will return later */ #ifdef FDC_YE case PIOREAD: /* @@ -1847,16 +1911,15 @@ fdstate(fdcu_t fdcu, fdc_p fdc) /* FALLTHROUGH */ #endif case IOCOMPLETE: /* IO DONE, post-analyze */ - untimeout(fd_iotimeout, (caddr_t)fdcu, fd->tohandle); + untimeout(fd_iotimeout, fdc, fd->tohandle); - if (fd_read_status(fdc, fd->fdsu)) - { + 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(fdcu); + return (retrier(fdc)); } fdc->state = IOTIMEDOUT; @@ -1869,8 +1932,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc) #endif isa_dmadone(bp->b_flags, bp->b_data + fd->skip, format ? bp->b_bcount : fdblk, fdc->dmachan); - if (fdc->status[0] & NE7_ST0_IC) - { + if (fdc->status[0] & NE7_ST0_IC) { if ((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT && fdc->status[1] & NE7_ST1_OR) { /* @@ -1890,17 +1952,14 @@ fdstate(fdcu_t fdcu, fdc_p fdc) && fdc->status[2] & NE7_ST2_WC && fdc->retry < 3) fdc->retry = 3; /* force recalibrate */ - return(retrier(fdcu)); + return (retrier(fdc)); } /* All OK */ fd->skip += fdblk; - if (!format && fd->skip < bp->b_bcount - bp->b_resid) - { + if (!format && fd->skip < bp->b_bcount - bp->b_resid) { /* set up next transfer */ fdc->state = DOSEEK; - } - else - { + } else { /* ALL DONE */ fd->skip = 0; fdc->bp = NULL; @@ -1915,7 +1974,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc) fdc->fdu = -1; fdc->state = FINDWORK; } - return(1); + return (1); case RESETCTLR: fdc_reset(fdc); fdc->retry++; @@ -1931,21 +1990,18 @@ fdstate(fdcu_t fdcu, fdc_p fdc) fdc->state = STARTRECAL; /* Fall through. */ case STARTRECAL: - if(fd_cmd(fdcu, - 2, NE7CMD_RECAL, fdu, - 0)) /* Recalibrate Function */ - { + if(fd_cmd(fdc, 2, NE7CMD_RECAL, fdu, 0)) { /* arrgl */ fdc->retry = 6; - return(retrier(fdcu)); + return (retrier(fdc)); } fdc->state = RECALWAIT; - return(0); /* will return later */ + return (0); /* will return later */ case RECALWAIT: /* allow heads to settle */ - timeout(fd_pseudointr, (caddr_t)fdcu, hz / 8); + timeout(fd_pseudointr, fdc, hz / 8); fdc->state = RECALCOMPLETE; - return(0); /* will return later */ + return (0); /* will return later */ case RECALCOMPLETE: do { /* @@ -1971,16 +2027,16 @@ fdstate(fdcu_t fdcu, fdc_p fdc) printf("fd%d: recal failed ST0 %b cyl %d\n", fdu, st0, NE7_ST0BITS, cyl); if(fdc->retry < 3) fdc->retry = 3; - return(retrier(fdcu)); + return (retrier(fdc)); } fd->track = 0; /* Seek (probably) necessary */ fdc->state = DOSEEK; - return(1); /* will return immediatly */ + return (1); /* will return immediatly */ case MOTORWAIT: if(fd->flags & FD_MOTOR_WAIT) { - return(0); /* time's not up yet */ + return (0); /* time's not up yet */ } if (fdc->flags & FDC_NEEDS_RESET) { fdc->state = RESETCTLR; @@ -1993,9 +2049,10 @@ fdstate(fdcu_t fdcu, fdc_p fdc) */ fdc->state = STARTRECAL; } - return(1); /* will return immediatly */ + return (1); /* will return immediatly */ default: - printf("fdc%d: Unexpected FD int->", fdcu); + device_print_prettyname(fdc->fdc_dev); + printf("unexpected FD int->"); if (fd_read_status(fdc, fd->fdsu) == 0) printf("FDC status :%x %x %x %x %x %x %x ", fdc->status[0], @@ -2010,28 +2067,31 @@ fdstate(fdcu_t fdcu, fdc_p fdc) if (fd_sense_int(fdc, &st0, &cyl) != 0) { printf("[controller is dead now]\n"); - return(0); + return (0); } printf("ST0 = %x, PCN = %x\n", st0, cyl); - return(0); + return (0); } /*XXX confusing: some branches return immediately, others end up here*/ - return(1); /* Come back immediatly to new state */ + return (1); /* Come back immediatly to new state */ } static int -retrier(fdcu) - fdcu_t fdcu; +retrier(struct fdc_data *fdc) { - fdc_p fdc = fdc_data + fdcu; register struct buf *bp; + struct fd_data *fd; + int fdu; bp = fdc->bp; - if(fd_data[FDUNIT(minor(bp->b_dev))].options & FDOPT_NORETRY) + /* XXX shouldn't this be cached somewhere? */ + fdu = FDUNIT(minor(bp->b_dev)); + fd = devclass_get_softc(fd_devclass, fdu); + if (fd->options & FDOPT_NORETRY) goto fail; - switch(fdc->retry) - { + + switch (fdc->retry) { case 0: case 1: case 2: fdc->state = SEEKCOMPLETE; break; @@ -2084,10 +2144,10 @@ retrier(fdcu) fdc->flags |= FDC_NEEDS_RESET; fdc->fd = (fd_p) 0; fdc->fdu = -1; - return(1); + return (1); } fdc->retry++; - return(1); + return (1); } static int @@ -2104,7 +2164,7 @@ fdformat(dev, finfo, p) size_t fdblk; fdu = FDUNIT(minor(dev)); - fd = &fd_data[fdu]; + fd = devclass_get_softc(fd_devclass, fdu); fdblk = 128 << fd->ft->secsize; /* set up a buffer header for fdstrategy() */ @@ -2135,20 +2195,19 @@ fdformat(dev, finfo, p) /* ...and wait for it to complete */ s = splbio(); - while(!(bp->b_flags & B_DONE)) - { + while(!(bp->b_flags & B_DONE)) { rv = tsleep((caddr_t)bp, PRIBIO, "fdform", 20 * hz); - if(rv == EWOULDBLOCK) + if (rv == EWOULDBLOCK) break; } splx(s); - if(rv == EWOULDBLOCK) { + if (rv == EWOULDBLOCK) { /* timed out */ rv = EIO; biodone(bp); } - if(bp->b_flags & B_ERROR) + if (bp->b_flags & B_ERROR) rv = bp->b_error; /* * allow the process to be swapped @@ -2171,7 +2230,7 @@ fdioctl(dev, cmd, addr, flag, p) struct proc *p; { fdu_t fdu = FDUNIT(minor(dev)); - fd_p fd = &fd_data[fdu]; + fd_p fd = devclass_get_softc(fd_devclass, fdu); size_t fdblk; struct fd_type *fdt; @@ -2181,13 +2240,12 @@ fdioctl(dev, cmd, addr, flag, p) fdblk = 128 << fd->ft->secsize; - switch (cmd) - { + switch (cmd) { case DIOCGDINFO: bzero(buffer, sizeof (buffer)); dl = (struct disklabel *)buffer; dl->d_secsize = fdblk; - fdt = fd_data[FDUNIT(minor(dev))].ft; + fdt = fd->ft; dl->d_secpercyl = fdt->size / fdt->tracks; dl->d_type = DTYPE_FLOPPY; @@ -2211,8 +2269,7 @@ fdioctl(dev, cmd, addr, flag, p) break; case DIOCWDINFO: - if ((flag & FWRITE) == 0) - { + if ((flag & FWRITE) == 0) { error = EBADF; break; } @@ -2227,9 +2284,9 @@ fdioctl(dev, cmd, addr, flag, p) (struct disklabel *)buffer); break; case FD_FORM: - if((flag & FWRITE) == 0) + if ((flag & FWRITE) == 0) error = EBADF; /* must be opened for writing */ - else if(((struct fd_formb *)addr)->format_version != + else if (((struct fd_formb *)addr)->format_version != FD_FORMAT_VERSION) error = EINVAL; /* wrong version of formatting prog */ else @@ -2242,7 +2299,7 @@ fdioctl(dev, cmd, addr, flag, p) case FD_STYPE: /* set drive type */ /* this is considered harmful; only allow for superuser */ - if(suser(p->p_ucred, &p->p_acflag) != 0) + if (suser(p->p_ucred, &p->p_acflag) != 0) return EPERM; *fd->ft = *(struct fd_type *)addr; break; @@ -2262,22 +2319,62 @@ fdioctl(dev, cmd, addr, flag, p) return (error); } +static device_method_t fdc_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, fdc_probe), + DEVMETHOD(device_attach, fdc_attach), + DEVMETHOD(device_detach, bus_generic_detach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + DEVMETHOD(device_suspend, bus_generic_suspend), + DEVMETHOD(device_resume, bus_generic_resume), -static fd_devsw_installed = 0; + /* Bus interface */ + DEVMETHOD(bus_print_child, fdc_print_child), + /* Our children never use any other bus interface methods. */ -static void fd_drvinit(void *notused ) -{ + { 0, 0 } +}; - if( ! fd_devsw_installed ) { - cdevsw_add_generic(BDEV_MAJOR,CDEV_MAJOR, &fd_cdevsw); - fd_devsw_installed = 1; - } -} +static driver_t fdc_driver = { + "fdc", + fdc_methods, + DRIVER_TYPE_BIO, + sizeof(struct fdc_data) +}; -SYSINIT(fddev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,fd_drvinit,NULL) +DRIVER_MODULE(fdc, isa, fdc_driver, fdc_devclass, 0, 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 */ -#endif + { 0, 0 } +}; + +static driver_t fd_driver = { + "fd", + fd_methods, + DRIVER_TYPE_BIO, + sizeof(struct fd_data) +}; + +static struct cdevsw fd_cdevsw = { + Fdopen, fdclose, fdread, fdwrite, + fdioctl, nostop, nullreset, nodevtotty, + seltrue, nommap, fdstrategy, "fd", + NULL, -1, nodump, nopsize, + D_DISK, 0, -1 +}; + +BDEV_DRIVER_MODULE(fd, fdc, fd_driver, fd_devclass, BDEV_MAJOR, CDEV_MAJOR, + fd_cdevsw, 0, 0); + +#endif /* NFDC > 0 */ /* * Hello emacs, these are the diff --git a/sys/dev/fxp/if_fxp.c b/sys/dev/fxp/if_fxp.c index 77f0ade1d5af..53b8d4db00c6 100644 --- a/sys/dev/fxp/if_fxp.c +++ b/sys/dev/fxp/if_fxp.c @@ -27,7 +27,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: if_fxp.c,v 1.65 1999/03/17 16:44:53 luigi Exp $ + * $Id: if_fxp.c,v 1.66 1999/03/20 04:51:25 wes Exp $ */ /* @@ -89,6 +89,10 @@ #else /* __FreeBSD__ */ #include <sys/sockio.h> +#include <sys/bus.h> +#include <machine/bus.h> +#include <sys/rman.h> +#include <machine/resource.h> #include <net/ethernet.h> #include <net/if_arp.h> @@ -491,51 +495,31 @@ fxp_ether_ioctl(ifp, cmd, data) #else /* __FreeBSD__ */ -static u_long fxp_count; -static const char *fxp_probe __P((pcici_t, pcidi_t)); -static void fxp_attach __P((pcici_t, int)); - -static void fxp_shutdown __P((int, void *)); - -static struct pci_device fxp_device = { - "fxp", - fxp_probe, - fxp_attach, - &fxp_count, - NULL -}; -DATA_SET(pcidevice_set, fxp_device); - /* * Return identification string if this is device is ours. */ -static const char * -fxp_probe(config_id, device_id) - pcici_t config_id; - pcidi_t device_id; +static int +fxp_probe(device_t dev) { - if (((device_id & 0xffff) == FXP_VENDORID_INTEL) && - ((device_id >> 16) & 0xffff) == FXP_DEVICEID_i82557) - return ("Intel EtherExpress Pro 10/100B Ethernet"); + if ((pci_get_vendor(dev) == FXP_VENDORID_INTEL) && + (pci_get_device(dev) == FXP_DEVICEID_i82557)) { + device_set_desc(dev, "Intel EtherExpress Pro 10/100B Ethernet"); + return 0; + } - return NULL; + return ENXIO; } -static void -fxp_attach(config_id, unit) - pcici_t config_id; - int unit; +static int +fxp_attach(device_t dev) { - struct fxp_softc *sc; - vm_offset_t pbase; + int error = 0; + struct fxp_softc *sc = device_get_softc(dev); struct ifnet *ifp; int s; u_long val; + int rid; - sc = malloc(sizeof(struct fxp_softc), M_DEVBUF, M_NOWAIT); - if (sc == NULL) - return; - bzero(sc, sizeof(struct fxp_softc)); callout_handle_init(&sc->stat_ch); s = splimp(); @@ -543,39 +527,56 @@ fxp_attach(config_id, unit) /* * Enable bus mastering. */ - val = pci_conf_read(config_id, PCI_COMMAND_STATUS_REG); + val = pci_read_config(dev, PCIR_COMMAND, 2); val |= (PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN); - pci_conf_write(config_id, PCI_COMMAND_STATUS_REG, val); + pci_write_config(dev, PCIR_COMMAND, val, 2); /* * Map control/status registers. */ - if (!pci_map_mem(config_id, FXP_PCI_MMBA, - (vm_offset_t *)&sc->csr, &pbase)) { - printf("fxp%d: couldn't map memory\n", unit); + rid = FXP_PCI_MMBA; + sc->mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, + 0, ~0, 1, RF_ACTIVE); + if (!sc->mem) { + device_printf(dev, "could not map memory\n"); + error = ENXIO; goto fail; - } + } + sc->csr = rman_get_virtual(sc->mem); /* XXX use bus_space */ /* * Allocate our interrupt. */ - if (!pci_map_int(config_id, fxp_intr, sc, &net_imask)) { - printf("fxp%d: couldn't map interrupt\n", unit); + rid = 0; + sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, + RF_SHAREABLE | RF_ACTIVE); + if (sc->irq == NULL) { + device_printf(dev, "could not map interrupt\n"); + error = ENXIO; + goto fail; + } + + error = bus_setup_intr(dev, sc->irq, fxp_intr, sc, &sc->ih); + if (error) { + device_printf(dev, "could not setup irq\n"); goto fail; } /* Do generic parts of attach. */ if (fxp_attach_common(sc, sc->arpcom.ac_enaddr)) { /* Failed! */ - (void) pci_unmap_int(config_id); + bus_teardown_intr(dev, sc->irq, sc->ih); + bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq); + bus_release_resource(dev, SYS_RES_MEMORY, FXP_PCI_MMBA, sc->mem); + error = ENXIO; goto fail; } - printf("fxp%d: Ethernet address %6D%s\n", unit, + device_printf(dev, "Ethernet address %6D%s\n", sc->arpcom.ac_enaddr, ":", sc->phy_10Mbps_only ? ", 10Mbps" : ""); ifp = &sc->arpcom.ac_if; - ifp->if_unit = unit; + ifp->if_unit = device_get_unit(dev); ifp->if_name = "fxp"; ifp->if_output = ether_output; ifp->if_baudrate = 100000000; @@ -600,19 +601,63 @@ fxp_attach(config_id, unit) bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header)); #endif + splx(s); + return 0; + + fail: + splx(s); + return error; +} + +/* + * Detach interface. + */ +static int +fxp_detach(device_t dev) +{ + struct fxp_softc *sc = device_get_softc(dev); + int s; + + s = splimp(); + /* - * Add shutdown hook so that DMA is disabled prior to reboot. Not - * doing do could allow DMA to corrupt kernel memory during the - * reboot before the driver initializes. + * Close down routes etc. */ - at_shutdown(fxp_shutdown, sc, SHUTDOWN_POST_SYNC); + if_detach(&sc->arpcom.ac_if); - splx(s); - return; + /* + * Stop DMA and drop transmit queue. + */ + fxp_stop(sc); + + /* + * Deallocate resources. + */ + bus_teardown_intr(dev, sc->irq, sc->ih); + bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq); + bus_release_resource(dev, SYS_RES_MEMORY, FXP_PCI_MMBA, sc->mem); + + /* + * Free all the receive buffers. + */ + if (sc->rfa_headm != NULL) + m_freem(sc->rfa_headm); + + /* + * Free all media structures. + */ + ifmedia_removeall(&sc->sc_media); + + /* + * Free anciliary structures. + */ + free(sc->cbl_base, M_DEVBUF); + free(sc->fxp_stats, M_DEVBUF); + free(sc->mcsp, M_DEVBUF); - fail: - free(sc, M_DEVBUF); splx(s); + + return 0; } /* @@ -620,14 +665,39 @@ fxp_attach(config_id, unit) * main purpose of this routine is to shut off receiver DMA so that * kernel memory doesn't get clobbered during warmboot. */ -static void -fxp_shutdown(howto, sc) - int howto; - void *sc; +static int +fxp_shutdown(device_t dev) { - fxp_stop((struct fxp_softc *) sc); + /* + * Make sure that DMA is disabled prior to reboot. Not doing + * do could allow DMA to corrupt kernel memory during the + * reboot before the driver initializes. + */ + fxp_stop((struct fxp_softc *) device_get_softc(dev)); + return 0; } +static device_method_t fxp_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, fxp_probe), + DEVMETHOD(device_attach, fxp_attach), + DEVMETHOD(device_detach, fxp_detach), + DEVMETHOD(device_shutdown, fxp_shutdown), + + { 0, 0 } +}; + +static driver_t fxp_driver = { + "fxp", + fxp_methods, + DRIVER_TYPE_NET, + sizeof(struct fxp_softc), +}; + +static devclass_t fxp_devclass; + +DRIVER_MODULE(fxp, pci, fxp_driver, fxp_devclass, 0, 0); + #endif /* __NetBSD__ */ /************************************************************* diff --git a/sys/dev/fxp/if_fxpvar.h b/sys/dev/fxp/if_fxpvar.h index ce8d8fe9de6d..042d2df96284 100644 --- a/sys/dev/fxp/if_fxpvar.h +++ b/sys/dev/fxp/if_fxpvar.h @@ -27,7 +27,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: if_fxpvar.h,v 1.5 1998/06/07 17:12:38 dfr Exp $ + * $Id: if_fxpvar.h,v 1.6 1998/08/02 00:29:15 dg Exp $ */ /* @@ -48,6 +48,9 @@ struct fxp_softc { #else struct arpcom arpcom; /* per-interface network data */ caddr_t csr; /* control/status registers */ + struct resource *mem; /* resource descriptor for registers */ + struct resource *irq; /* resource descriptor for interrupt */ + void *ih; /* interrupt handler cookie */ #endif /* __NetBSD__ */ struct mbuf *rfa_headm; /* first mbuf in receive frame area */ struct mbuf *rfa_tailm; /* last mbuf in receive frame area */ diff --git a/sys/dev/kbd/atkbd.c b/sys/dev/kbd/atkbd.c index f9e28febe12e..80c81a5968a6 100644 --- a/sys/dev/kbd/atkbd.c +++ b/sys/dev/kbd/atkbd.c @@ -23,7 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: atkbd.c,v 1.4 1999/01/28 10:55:55 yokota Exp $ + * $Id: atkbd.c,v 1.5 1999/03/10 10:36:52 yokota Exp $ */ #include "atkbd.h" @@ -46,7 +46,7 @@ #include <dev/kbd/atkbdreg.h> #include <dev/kbd/atkbdcreg.h> -#ifndef __i386__ +#if 1 #include <sys/bus.h> #include <isa/isareg.h> @@ -89,6 +89,7 @@ static struct cdevsw atkbd_cdevsw = { #endif /* KBD_INSTALL_CDEV */ +#if 0 #ifdef __i386__ atkbd_softc_t @@ -110,6 +111,7 @@ atkbd_softc_t } #endif /* __i386__ */ +#endif int atkbd_probe_unit(int unit, int port, int irq, int flags) @@ -376,16 +378,14 @@ atkbd_configure(int flags) { keyboard_t *kbd; int arg[2]; -#ifdef __i386__ - struct isa_device *dev; int i; /* XXX: a kludge to obtain the device configuration flags */ - dev = find_isadev(isa_devtab_tty, &atkbddriver, 0); - if (dev != NULL) { - flags |= dev->id_flags; + if (resource_int_value("atkbd", 0, "flags", &i) == 0) { + flags |= i; /* if the driver is disabled, unregister the keyboard if any */ - if (!dev->id_enabled) { + if (resource_int_value("atkbd", 0, "disabled", &i) == 0 + && i != 0) { i = kbd_find_keyboard(ATKBD_DRIVER_NAME, ATKBD_DEFAULT); if (i >= 0) { kbd = kbd_get_keyboard(i); @@ -395,8 +395,7 @@ atkbd_configure(int flags) } } } -#endif - + /* probe the keyboard controller */ atkbdc_configure(); diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index e449fc25e50f..889550c9bc95 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -23,10 +23,12 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: pci.c,v 1.93 1999/01/19 23:29:18 se Exp $ + * $Id: pci.c,v 1.94 1999/04/11 02:47:31 eivind Exp $ * */ +#include "opt_bus.h" + #include "pci.h" #if NPCI > 0 @@ -50,6 +52,11 @@ #include <vm/pmap.h> #include <vm/vm_extern.h> +#include <sys/bus.h> +#include <machine/bus.h> +#include <sys/rman.h> +#include <machine/resource.h> + #include <pci/pcireg.h> #include <pci/pcivar.h> #include <pci/pci_ioctl.h> @@ -338,11 +345,10 @@ pci_readcfg(pcicfgregs *probe) M_DEVBUF, M_WAITOK); if (devlist_entry == NULL) return (NULL); + bzero(devlist_entry, sizeof *devlist_entry); cfg = &devlist_entry->cfg; - bzero(cfg, sizeof *cfg); - cfg->bus = probe->bus; cfg->slot = probe->slot; cfg->func = probe->func; @@ -450,113 +456,6 @@ pci_freecfg(struct pci_devinfo *dinfo) } #endif -static void -pci_addcfg(struct pci_devinfo *dinfo) -{ - if (bootverbose) { - int i; - pcicfgregs *cfg = &dinfo->cfg; - - printf("found->\tvendor=0x%04x, dev=0x%04x, revid=0x%02x\n", - cfg->vendor, cfg->device, cfg->revid); - printf("\tclass=%02x-%02x-%02x, hdrtype=0x%02x, mfdev=%d\n", - cfg->baseclass, cfg->subclass, cfg->progif, - cfg->hdrtype, cfg->mfdev); - printf("\tsubordinatebus=%x \tsecondarybus=%x\n", - cfg->subordinatebus, cfg->secondarybus); -#ifdef PCI_DEBUG - printf("\tcmdreg=0x%04x, statreg=0x%04x, cachelnsz=%d (dwords)\n", - cfg->cmdreg, cfg->statreg, cfg->cachelnsz); - printf("\tlattimer=0x%02x (%d ns), mingnt=0x%02x (%d ns), maxlat=0x%02x (%d ns)\n", - cfg->lattimer, cfg->lattimer * 30, - cfg->mingnt, cfg->mingnt * 250, cfg->maxlat, cfg->maxlat * 250); -#endif /* PCI_DEBUG */ - if (cfg->intpin > 0) - printf("\tintpin=%c, irq=%d\n", cfg->intpin +'a' -1, cfg->intline); - - for (i = 0; i < cfg->nummaps; i++) { - pcimap *m = &cfg->map[i]; - printf("\tmap[%d]: type %x, range %2d, base %08x, size %2d\n", - i, m->type, m->ln2range, m->base, m->ln2size); - } - } - pci_drvattach(dinfo); /* XXX currently defined in pci_compat.c */ -} - -/* scan one PCI bus for devices */ - -static int -pci_probebus(int bus) -{ - pcicfgregs probe; - int bushigh = bus; - -#ifdef SIMOS -#undef PCI_SLOTMAX -#define PCI_SLOTMAX 0 -#endif - - bzero(&probe, sizeof probe); - /* XXX KDM */ - /* probe.parent = pci_bridgeto(bus); */ - probe.bus = bus; - for (probe.slot = 0; probe.slot <= PCI_SLOTMAX; probe.slot++) { - int pcifunchigh = 0; - for (probe.func = 0; probe.func <= pcifunchigh; probe.func++) { - struct pci_devinfo *dinfo = pci_readcfg(&probe); - if (dinfo != NULL) { - if (dinfo->cfg.mfdev) - pcifunchigh = 7; - /* - * XXX: Temporarily move pci_addcfg() up before - * the use of cfg->subordinatebus. This is - * necessary, since pci_addcfg() calls the - * device's probe(), which may read the bus# - * from some device dependent register of - * some host to PCI bridges. The probe will - * eventually be moved to pci_readcfg(), and - * pci_addcfg() will then be moved back down - * below the conditional statement ... - */ - pci_addcfg(dinfo); - - if (bushigh < dinfo->cfg.subordinatebus) - bushigh = dinfo->cfg.subordinatebus; - if (bushigh < dinfo->cfg.secondarybus) - bushigh = dinfo->cfg.secondarybus; - - /* XXX KDM */ - /* cfg = NULL; we don't own this anymore ... */ - } - } - } - return (bushigh); -} - -/* scan a PCI bus tree reached through one PCI attachment point */ - -int -pci_probe(pciattach *parent) -{ - int bushigh; - int bus = 0; - - STAILQ_INIT(&pci_devq); - - bushigh = pci_bushigh(); - while (bus <= bushigh) { - int newbushigh; - - printf("Probing for devices on PCI bus %d:\n", bus); - newbushigh = pci_probebus(bus); - - if (bushigh < newbushigh) - bushigh = newbushigh; - bus++; - } - return (bushigh); -} - /* * This is the user interface to PCI configuration space. */ @@ -750,8 +649,8 @@ pci_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) "pci_match_conf) (%d)\npci_ioctl: " "pat_buf_len should be = %d\n", cio->pat_buf_len, cio->num_patterns, - sizeof(struct pci_match_conf), - sizeof(struct pci_match_conf) * + (int)sizeof(struct pci_match_conf), + (int)sizeof(struct pci_match_conf) * cio->num_patterns); printf("pci_ioctl: do your headers match your " "kernel?\n"); @@ -945,4 +844,534 @@ pci_cdevinit(void *dummy) SYSINIT(pcidev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE+PCI_CDEV, pci_cdevinit, NULL); +#include "pci_if.h" + +/* + * A simple driver to wrap the old pci driver mechanism for back-compat. + */ + +static int +pci_compat_probe(device_t dev) +{ + struct pci_device *dvp; + struct pci_devinfo *dinfo; + pcicfgregs *cfg; + const char *name; + int error; + + dinfo = device_get_ivars(dev); + cfg = &dinfo->cfg; + dvp = device_get_driver(dev)->priv; + + /* + * Do the wrapped probe. + */ + error = ENXIO; + if (dvp && dvp->pd_probe) { + name = dvp->pd_probe(cfg, (cfg->device << 16) + cfg->vendor); + if (name) { + device_set_desc_copy(dev, name); + error = 0; + } + } + + return error; +} + +static int +pci_compat_attach(device_t dev) +{ + struct pci_device *dvp; + struct pci_devinfo *dinfo; + pcicfgregs *cfg; + int unit; + + dinfo = device_get_ivars(dev); + cfg = &dinfo->cfg; + dvp = device_get_driver(dev)->priv; + + unit = device_get_unit(dev); + if (unit > *dvp->pd_count) + *dvp->pd_count = unit; + if (dvp->pd_attach) + dvp->pd_attach(cfg, unit); + + /* + * XXX KDM for some devices, dvp->pd_name winds up NULL. + * I haven't investigated enough to figure out why this + * would happen. + */ + if (dvp->pd_name != NULL) + strncpy(dinfo->conf.pd_name, dvp->pd_name, + sizeof(dinfo->conf.pd_name)); + else + strncpy(dinfo->conf.pd_name, "????", + sizeof(dinfo->conf.pd_name)); + dinfo->conf.pd_name[sizeof(dinfo->conf.pd_name) - 1] = 0; + dinfo->conf.pd_unit = unit; + + return 0; +} + +static device_method_t pci_compat_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, pci_compat_probe), + DEVMETHOD(device_attach, pci_compat_attach), + + { 0, 0 } +}; + +static devclass_t pci_devclass; + +/* + * Create a new style driver around each old pci driver. + */ +static void +pci_wrap_old_drivers(void) +{ + struct pci_device **dvpp, *dvp; + + dvpp = (struct pci_device **)pcidevice_set.ls_items; + while ((dvp = *dvpp++) != NULL) { + driver_t *driver; + driver = malloc(sizeof(driver_t), M_DEVBUF, M_NOWAIT); + if (!driver) + continue; + bzero(driver, sizeof(driver_t)); + driver->name = dvp->pd_name; + driver->methods = pci_compat_methods; + driver->type = 0; /* XXX fixup in pci_map_int() */ + driver->softc = sizeof(struct pci_devinfo *); + driver->priv = dvp; + devclass_add_driver(pci_devclass, driver); + } +} + +/* + * New style pci driver. Parent device is either a pci-host-bridge or a + * pci-pci-bridge. Both kinds are represented by instances of pcib. + */ + +static void +pci_print_verbose(struct pci_devinfo *dinfo) +{ + if (bootverbose) { + int i; + pcicfgregs *cfg = &dinfo->cfg; + + printf("found->\tvendor=0x%04x, dev=0x%04x, revid=0x%02x\n", + cfg->vendor, cfg->device, cfg->revid); + printf("\tclass=%02x-%02x-%02x, hdrtype=0x%02x, mfdev=%d\n", + cfg->baseclass, cfg->subclass, cfg->progif, + cfg->hdrtype, cfg->mfdev); + printf("\tsubordinatebus=%x \tsecondarybus=%x\n", + cfg->subordinatebus, cfg->secondarybus); +#ifdef PCI_DEBUG + printf("\tcmdreg=0x%04x, statreg=0x%04x, cachelnsz=%d (dwords)\n", + cfg->cmdreg, cfg->statreg, cfg->cachelnsz); + printf("\tlattimer=0x%02x (%d ns), mingnt=0x%02x (%d ns), maxlat=0x%02x (%d ns)\n", + cfg->lattimer, cfg->lattimer * 30, + cfg->mingnt, cfg->mingnt * 250, cfg->maxlat, cfg->maxlat * 250); +#endif /* PCI_DEBUG */ + if (cfg->intpin > 0) + printf("\tintpin=%c, irq=%d\n", cfg->intpin +'a' -1, cfg->intline); + + for (i = 0; i < cfg->nummaps; i++) { + pcimap *m = &cfg->map[i]; + printf("\tmap[%d]: type %x, range %2d, base %08x, size %2d\n", + i, m->type, m->ln2range, m->base, m->ln2size); + } + } +} + +static int +pci_add_children(device_t dev, int busno) +{ + pcicfgregs probe; + int bushigh = busno; + +#ifdef SIMOS +#undef PCI_SLOTMAX +#define PCI_SLOTMAX 0 +#endif + + bzero(&probe, sizeof probe); + /* XXX KDM */ + /* probe.parent = pci_bridgeto(bus); */ + probe.bus = busno; + for (probe.slot = 0; probe.slot <= PCI_SLOTMAX; probe.slot++) { + int pcifunchigh = 0; + for (probe.func = 0; probe.func <= pcifunchigh; probe.func++) { + struct pci_devinfo *dinfo = pci_readcfg(&probe); + if (dinfo != NULL) { + if (dinfo->cfg.mfdev) + pcifunchigh = 7; + + pci_print_verbose(dinfo); + dinfo->cfg.dev = + device_add_child(dev, NULL, -1, dinfo); + + if (bushigh < dinfo->cfg.subordinatebus) + bushigh = dinfo->cfg.subordinatebus; + if (bushigh < dinfo->cfg.secondarybus) + bushigh = dinfo->cfg.secondarybus; + } + } + } + + return bushigh; +} + +static int +pci_new_probe(device_t dev) +{ + STAILQ_INIT(&pci_devq); + device_set_desc(dev, "PCI bus"); + + pci_add_children(dev, device_get_unit(dev)); + + return 0; +} + +static void +pci_print_child(device_t dev, device_t child) +{ + printf(" at device %d.%d", pci_get_slot(child), pci_get_function(child)); + printf(" on %s%d", device_get_name(dev), device_get_unit(dev)); +} + +static int +pci_read_ivar(device_t dev, device_t child, int which, u_long *result) +{ + struct pci_devinfo *dinfo; + pcicfgregs *cfg; + + dinfo = device_get_ivars(child); + cfg = &dinfo->cfg; + + switch (which) { + case PCI_IVAR_SUBVENDOR: + *result = cfg->subvendor; + break; + case PCI_IVAR_SUBDEVICE: + *result = cfg->subdevice; + break; + case PCI_IVAR_VENDOR: + *result = cfg->vendor; + break; + case PCI_IVAR_DEVICE: + *result = cfg->device; + break; + case PCI_IVAR_DEVID: + *result = (cfg->device << 16) | cfg->vendor; + break; + case PCI_IVAR_CLASS: + *result = cfg->baseclass; + break; + case PCI_IVAR_SUBCLASS: + *result = cfg->subclass; + break; + case PCI_IVAR_PROGIF: + *result = cfg->progif; + break; + case PCI_IVAR_REVID: + *result = cfg->revid; + break; + case PCI_IVAR_INTPIN: + *result = cfg->intpin; + break; + case PCI_IVAR_IRQ: + *result = cfg->intline; + break; + case PCI_IVAR_BUS: + *result = cfg->bus; + break; + case PCI_IVAR_SLOT: + *result = cfg->slot; + break; + case PCI_IVAR_FUNCTION: + *result = cfg->func; + break; + case PCI_IVAR_SECONDARYBUS: + *result = cfg->secondarybus; + break; + case PCI_IVAR_SUBORDINATEBUS: + *result = cfg->subordinatebus; + break; + default: + return ENOENT; + } + return 0; +} + +static int +pci_write_ivar(device_t dev, device_t child, int which, uintptr_t value) +{ + struct pci_devinfo *dinfo; + pcicfgregs *cfg; + + dinfo = device_get_ivars(child); + cfg = &dinfo->cfg; + + switch (which) { + case PCI_IVAR_SUBVENDOR: + case PCI_IVAR_SUBDEVICE: + case PCI_IVAR_VENDOR: + case PCI_IVAR_DEVICE: + case PCI_IVAR_DEVID: + case PCI_IVAR_CLASS: + case PCI_IVAR_SUBCLASS: + case PCI_IVAR_PROGIF: + case PCI_IVAR_REVID: + case PCI_IVAR_INTPIN: + case PCI_IVAR_IRQ: + case PCI_IVAR_BUS: + case PCI_IVAR_SLOT: + case PCI_IVAR_FUNCTION: + return EINVAL; /* disallow for now */ + + case PCI_IVAR_SECONDARYBUS: + cfg->secondarybus = value; + break; + case PCI_IVAR_SUBORDINATEBUS: + cfg->subordinatebus = value; + break; + default: + return ENOENT; + } + return 0; +} + +static int +pci_mapno(pcicfgregs *cfg, int reg) +{ + int i, nummaps; + pcimap *map; + + nummaps = cfg->nummaps; + map = cfg->map; + + for (i = 0; i < nummaps; i++) + if (map[i].reg == reg) + return (i); + return (-1); +} + +static int +pci_porten(pcicfgregs *cfg) +{ + return ((cfg->cmdreg & PCIM_CMD_PORTEN) != 0); +} + +static int +pci_isportmap(pcicfgregs *cfg, int map) + +{ + return ((unsigned)map < cfg->nummaps + && (cfg->map[map].type & PCI_MAPPORT) != 0); +} + +static int +pci_memen(pcicfgregs *cfg) +{ + return ((cfg->cmdreg & PCIM_CMD_MEMEN) != 0); +} + +static int +pci_ismemmap(pcicfgregs *cfg, int map) +{ + return ((unsigned)map < cfg->nummaps + && (cfg->map[map].type & PCI_MAPMEM) != 0); +} + +static struct resource * +pci_alloc_resource(device_t dev, device_t child, int type, int *rid, + u_long start, u_long end, u_long count, u_int flags) +{ + int isdefault; + struct pci_devinfo *dinfo = device_get_ivars(child); + pcicfgregs *cfg = &dinfo->cfg; + struct resource *rv, **rvp = 0; + int map; + + isdefault = (device_get_parent(child) == dev + && start == 0UL && end == ~0UL && count == 1); + + switch (type) { + case SYS_RES_IRQ: + if (*rid != 0) + return 0; + if (isdefault && cfg->intline != 255) { + start = cfg->intline; + end = cfg->intline; + count = 1; + } + break; + + case SYS_RES_DRQ: /* passthru for child isa */ + break; + + case SYS_RES_MEMORY: + if (isdefault) { + map = pci_mapno(cfg, *rid); + if (pci_memen(cfg) && pci_ismemmap(cfg, map)) { + start = cfg->map[map].base; + count = 1 << cfg->map[map].ln2size; + end = start + count; + rvp = &cfg->map[map].res; + } else + return 0; + } + break; + + case SYS_RES_IOPORT: + if (isdefault) { + map = pci_mapno(cfg, *rid); + if (pci_porten(cfg) && pci_isportmap(cfg, map)) { + start = cfg->map[map].base; + count = 1 << cfg->map[map].ln2size; + end = start + count; + rvp = &cfg->map[map].res; + } else + return 0; + } + break; + + default: + return 0; + } + + rv = BUS_ALLOC_RESOURCE(device_get_parent(dev), child, + type, rid, start, end, count, flags); + if (rvp) + *rvp = rv; + + return rv; +} + +static int +pci_release_resource(device_t dev, device_t child, int type, int rid, + struct resource *r) +{ + int rv; + struct pci_devinfo *dinfo = device_get_ivars(child); + pcicfgregs *cfg = &dinfo->cfg; + int map = 0; + + switch (type) { + case SYS_RES_IRQ: + if (rid != 0) + return EINVAL; + break; + + case SYS_RES_DRQ: /* passthru for child isa */ + break; + + case SYS_RES_MEMORY: + case SYS_RES_IOPORT: + /* + * Only check the map registers if this is a direct + * descendant. + */ + if (device_get_parent(child) == dev) + map = pci_mapno(cfg, rid); + else + map = -1; + break; + + default: + return (ENOENT); + } + + rv = BUS_RELEASE_RESOURCE(device_get_parent(dev), child, type, rid, r); + + if (rv == 0) { + switch (type) { + case SYS_RES_IRQ: + cfg->irqres = 0; + break; + + case SYS_RES_DRQ: /* passthru for child isa */ + break; + + case SYS_RES_MEMORY: + case SYS_RES_IOPORT: + if (map != -1) + cfg->map[map].res = 0; + break; + + default: + return ENOENT; + } + } + + return rv; +} + +static u_int32_t +pci_read_config_method(device_t dev, device_t child, int reg, int width) +{ + struct pci_devinfo *dinfo = device_get_ivars(child); + pcicfgregs *cfg = &dinfo->cfg; + return pci_cfgread(cfg, reg, width); +} + +static void +pci_write_config_method(device_t dev, device_t child, int reg, + u_int32_t val, int width) +{ + struct pci_devinfo *dinfo = device_get_ivars(child); + pcicfgregs *cfg = &dinfo->cfg; + pci_cfgwrite(cfg, reg, val, width); +} + +static int +pci_modevent(module_t mod, int what, void *arg) +{ + switch (what) { + case MOD_LOAD: + pci_wrap_old_drivers(); + break; + + case MOD_UNLOAD: + break; + } + + return 0; +} + +static device_method_t pci_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, pci_new_probe), + DEVMETHOD(device_attach, bus_generic_attach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + + /* Bus interface */ + DEVMETHOD(bus_print_child, pci_print_child), + DEVMETHOD(bus_read_ivar, pci_read_ivar), + DEVMETHOD(bus_write_ivar, pci_write_ivar), + DEVMETHOD(bus_driver_added, bus_generic_driver_added), + DEVMETHOD(bus_alloc_resource, pci_alloc_resource), + DEVMETHOD(bus_release_resource, pci_release_resource), + DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), + DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), + DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), + DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), + + /* PCI interface */ + DEVMETHOD(pci_read_config, pci_read_config_method), + DEVMETHOD(pci_write_config, pci_write_config_method), + + { 0, 0 } +}; + +static driver_t pci_driver = { + "pci", + pci_methods, + DRIVER_TYPE_MISC, + 1, /* no softc */ +}; + +DRIVER_MODULE(pci, pcib, pci_driver, pci_devclass, pci_modevent, 0); + #endif /* NPCI > 0 */ diff --git a/sys/dev/pci/pci_if.m b/sys/dev/pci/pci_if.m new file mode 100644 index 000000000000..b2fa6758fef6 --- /dev/null +++ b/sys/dev/pci/pci_if.m @@ -0,0 +1,44 @@ +# +# Copyright (c) 1998 Doug Rabson +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. +# +# $Id$ +# + +INTERFACE pci; + +METHOD u_int32_t read_config { + device_t dev; + device_t child; + int reg; + int width; +}; + +METHOD void write_config { + device_t dev; + device_t child; + int reg; + u_int32_t val; + int width; +}; diff --git a/sys/dev/pci/pcireg.h b/sys/dev/pci/pcireg.h index 0adb5404021e..9c0dba09331d 100644 --- a/sys/dev/pci/pcireg.h +++ b/sys/dev/pci/pcireg.h @@ -26,7 +26,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: pcireg.h,v 1.19 1997/09/20 07:41:58 dyson Exp $ + * $Id: pcireg.h,v 1.20 1998/10/07 03:40:51 gibbs Exp $ * */ @@ -173,7 +173,7 @@ #define PCIS_MEMORY_OTHER 0x80 #define PCIC_BRIDGE 0x06 -#define PCIS_BRDIGE_HOST 0x00 +#define PCIS_BRIDGE_HOST 0x00 #define PCIS_BRIDGE_ISA 0x01 #define PCIS_BRIDGE_EISA 0x02 #define PCIS_BRIDGE_MCA 0x03 diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h index 7843e3a6d656..55f72a16b875 100644 --- a/sys/dev/pci/pcivar.h +++ b/sys/dev/pci/pcivar.h @@ -23,7 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: pcivar.h,v 1.24 1999/01/13 04:59:19 bde Exp $ + * $Id: pcivar.h,v 1.25 1999/01/19 23:29:20 se Exp $ * */ @@ -67,13 +67,17 @@ typedef struct { u_int8_t ln2size; u_int8_t ln2range; u_int8_t reg; /* offset of map register in config space */ +/* u_int8_t dummy;*/ + struct resource *res; /* handle from resource manager */ } pcimap; /* config header information common to all header types */ typedef struct pcicfg { + struct device *dev; /* device which owns this */ pcimap *map; /* pointer to array of PCI maps */ void *hdrspec; /* pointer to header type specific data */ + struct resource *irqres; /* resource descriptor for interrupt mapping */ u_int16_t subvendor; /* card vendor ID */ u_int16_t subdevice; /* card device ID, assigned by card vendor */ @@ -182,6 +186,79 @@ void pci_cfgwrite (pcicfgregs *cfg, int reg, int data, int bytes); vm_offset_t pci_cvt_to_dense (vm_offset_t); vm_offset_t pci_cvt_to_bwx (vm_offset_t); #endif /* __alpha__ */ + +#ifdef _SYS_BUS_H_ + +#include "pci_if.h" + +enum pci_device_ivars { + PCI_IVAR_SUBVENDOR, + PCI_IVAR_SUBDEVICE, + PCI_IVAR_VENDOR, + PCI_IVAR_DEVICE, + PCI_IVAR_DEVID, + PCI_IVAR_CLASS, + PCI_IVAR_SUBCLASS, + PCI_IVAR_PROGIF, + PCI_IVAR_REVID, + PCI_IVAR_INTPIN, + PCI_IVAR_IRQ, + PCI_IVAR_BUS, + PCI_IVAR_SLOT, + PCI_IVAR_FUNCTION, + PCI_IVAR_SECONDARYBUS, + PCI_IVAR_SUBORDINATEBUS, +}; + +/* + * Simplified accessors for pci devices + */ +#define PCI_ACCESSOR(A, B, T) \ + \ +static __inline T pci_get_ ## A(device_t dev) \ +{ \ + uintptr_t v; \ + BUS_READ_IVAR(device_get_parent(dev), dev, PCI_IVAR_ ## B, &v); \ + return (T) v; \ +} \ + \ +static __inline void pci_set_ ## A(device_t dev, T t) \ +{ \ + u_long v = (u_long) t; \ + BUS_WRITE_IVAR(device_get_parent(dev), dev, PCI_IVAR_ ## B, v); \ +} + +PCI_ACCESSOR(subvendor, SUBVENDOR, u_int16_t) +PCI_ACCESSOR(subdevice, SUBDEVICE, u_int16_t) +PCI_ACCESSOR(vendor, VENDOR, u_int16_t) +PCI_ACCESSOR(device, DEVICE, u_int16_t) +PCI_ACCESSOR(devid, DEVID, u_int32_t) +PCI_ACCESSOR(class, CLASS, u_int8_t) +PCI_ACCESSOR(subclass, SUBCLASS, u_int8_t) +PCI_ACCESSOR(progif, PROGIF, u_int8_t) +PCI_ACCESSOR(revid, REVID, u_int8_t) +PCI_ACCESSOR(intpin, INTPIN, u_int8_t) +PCI_ACCESSOR(irq, IRQ, u_int8_t) +PCI_ACCESSOR(bus, BUS, u_int8_t) +PCI_ACCESSOR(slot, SLOT, u_int8_t) +PCI_ACCESSOR(function, FUNCTION, u_int8_t) +PCI_ACCESSOR(secondarybus, SECONDARYBUS, u_int8_t) +PCI_ACCESSOR(subordinatebus, SUBORDINATEBUS, u_int8_t) + +static __inline u_int32_t +pci_read_config(device_t dev, int reg, int width) +{ + return PCI_READ_CONFIG(device_get_parent(dev), dev, reg, width); +} + +static __inline void +pci_write_config(device_t dev, int reg, u_int32_t val, int width) +{ + PCI_WRITE_CONFIG(device_get_parent(dev), dev, reg, val, width); +} + +#endif + /* for compatibility to FreeBSD-2.2 version of PCI code */ #ifdef PCI_COMPAT diff --git a/sys/dev/rp/rp.c b/sys/dev/rp/rp.c index 3ac4ee90dad6..e9357fadc51b 100644 --- a/sys/dev/rp/rp.c +++ b/sys/dev/rp/rp.c @@ -1180,7 +1180,6 @@ int rpattach(dev) struct isa_device *dev; { - struct isa_device *idev; dev_t rp_dev; int iobase, unit, /*rpmajor,*/ oldspl; int num_ports, num_chan, num_aiops; @@ -1280,13 +1279,6 @@ struct isa_device *dev; } } - idev = find_isadev(isa_devtab_tty, &rpdriver, - RP_MPMASTER(dev) + rp_pcicount); - if(idev == NULL) { - printf("rp%d: master device %d not configured\n", - dev->id_unit, RP_MPMASTER(dev)); - } -/* printf("COOL!! Device is found!!\n"); for(rpmajor=0;rpmajor<nchrdev;rpmajor++) if(cdevsw[rpmajor].d_open == rpopen) printf("From %d entries: Found entry at major = %d\n",nchrdev,rpmajor); diff --git a/sys/dev/sio/sio.c b/sys/dev/sio/sio.c index ee031b46e533..1a40360691c6 100644 --- a/sys/dev/sio/sio.c +++ b/sys/dev/sio/sio.c @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: sio.c,v 1.220 1999/01/19 00:21:47 peter Exp $ + * $Id: sio.c,v 1.221 1999/01/30 12:17:35 phk Exp $ * from: @(#)com.c 7.5 (Berkeley) 5/16/91 * from: i386/isa sio.c,v 1.215 */ @@ -68,6 +68,7 @@ #include <sys/syslog.h> #include <sys/sysctl.h> #include <sys/bus.h> +#include <machine/bus.h> #include <sys/rman.h> #ifdef DEVFS #include <sys/devfsext.h> @@ -103,8 +104,10 @@ #endif +#ifndef __i386__ #define disable_intr() 0 #define enable_intr() 0 +#endif #ifdef SMP #define disable_intr() COM_DISABLE_INTR() @@ -2607,6 +2610,21 @@ static void siocnclose __P((struct siocnstate *sp, Port_t iobase)); static void siocnopen __P((struct siocnstate *sp, Port_t iobase, int speed)); static void siocntxwait __P((Port_t iobase)); +#ifdef __i386__ +/* + * XXX: sciocnget() and sciocnputc() are not declared static, as they are + * referred to from i386/i386/i386-gdbstub.c. + */ +static cn_probe_t siocnprobe; +static cn_init_t siocninit; +static cn_checkc_t siocncheckc; + cn_getc_t siocngetc; + cn_putc_t siocnputc; + +CONS_DRIVER(sio, siocnprobe, siocninit, siocngetc, siocncheckc, siocnputc); + +#endif + static void siocntxwait(iobase) Port_t iobase; @@ -2731,11 +2749,9 @@ void siocnprobe(cp) struct consdev *cp; { -#if 0 speed_t boot_speed; u_char cfcr; - struct isa_device *dvp; - int s; + int s, unit; struct siocnstate sp; /* @@ -2753,10 +2769,16 @@ siocnprobe(cp) * don't need to probe. */ cp->cn_pri = CN_DEAD; - for (dvp = isa_devtab_tty; dvp->id_driver != NULL; dvp++) - if (dvp->id_driver == &siodriver && dvp->id_enabled - && COM_CONSOLE(dvp)) { - siocniobase = dvp->id_iobase; + + for (unit = 0; unit < 16; unit++) { /* XXX need to know how many */ + int flags; + if (resource_int_value("sio", unit, "flags", &flags)) + continue; + if (COM_CONSOLE(flags)) { + int port; + if (resource_int_value("sio", unit, "port", &port)) + continue; + siocniobase = port; s = spltty(); if (boothowto & RB_SERIAL) { boot_speed = siocngetspeed(siocniobase, @@ -2784,17 +2806,19 @@ siocnprobe(cp) siocnopen(&sp, siocniobase, comdefaultrate); splx(s); - if (!COM_LLCONSOLE(dvp)) { - cp->cn_dev = makedev(CDEV_MAJOR, dvp->id_unit); - cp->cn_pri = COM_FORCECONSOLE(dvp) + if (!COM_LLCONSOLE(flags)) { + cp->cn_dev = makedev(CDEV_MAJOR, unit); + cp->cn_pri = COM_FORCECONSOLE(flags) || boothowto & RB_SERIAL ? CN_REMOTE : CN_NORMAL; } break; } -#endif + } } +#ifdef __alpha__ + struct consdev siocons = { NULL, NULL, siocngetc, siocncheckc, siocnputc, NULL, makedev(CDEV_MAJOR, 0), CN_NORMAL, @@ -2877,6 +2901,8 @@ siogdbattach(port, speed) return 0; } +#endif + void siocninit(cp) struct consdev *cp; @@ -3158,7 +3184,6 @@ static void siopnp_attach(u_long csn, u_long vend_id, char *name, struct isa_device *dev) { struct pnp_cinfo d; - struct isa_device *dvp; if (dev->id_unit >= NSIOTOT) return; @@ -3180,9 +3205,7 @@ siopnp_attach(u_long csn, u_long vend_id, char *name, struct isa_device *dev) if (dev->id_driver == NULL) { dev->id_driver = &siodriver; - dvp = find_isadev(isa_devtab_tty, &siodriver, 0); - if (dvp != NULL) - dev->id_id = dvp->id_id; + dev->id_id = isa_compat_nextid(); } if ((dev->id_alive = sioprobe(dev)) != 0) diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c index a874dbb21fc5..a2db9b489c72 100644 --- a/sys/dev/syscons/syscons.c +++ b/sys/dev/syscons/syscons.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: syscons.c,v 1.298 1999/02/05 11:52:11 yokota Exp $ + * $Id: syscons.c,v 1.299 1999/03/10 10:36:53 yokota Exp $ */ #include "sc.h" @@ -1869,6 +1869,7 @@ extern struct isa_driver scdriver; static void sccnprobe(struct consdev *cp) { +#if 0 struct isa_device *dvp; /* @@ -1885,6 +1886,13 @@ sccnprobe(struct consdev *cp) return; } sckbdprobe(dvp->id_unit, dvp->id_flags, TRUE); +#else + if (!scvidprobe(0, 0, TRUE)) { + cp->cn_pri = CN_DEAD; + return; + } + sckbdprobe(0, 0, TRUE); +#endif /* initialize required fields */ cp->cn_dev = makedev(CDEV_MAJOR, SC_CONSOLE); diff --git a/sys/dev/usb/ohci.c b/sys/dev/usb/ohci.c index 334a998aa277..b97fee07909e 100644 --- a/sys/dev/usb/ohci.c +++ b/sys/dev/usb/ohci.c @@ -59,6 +59,10 @@ #include <sys/queue.h> #include <sys/select.h> +#ifdef __FreeBSD__ +#include <machine/bus_pio.h> +#include <machine/bus_memio.h> +#endif #include <machine/bus.h> #include <machine/endian.h> @@ -162,15 +166,9 @@ void ohci_dump_td __P((ohci_soft_td_t *)); void ohci_dump_ed __P((ohci_soft_ed_t *)); #endif -#if defined(__NetBSD__) #define OWRITE4(sc, r, x) bus_space_write_4((sc)->iot, (sc)->ioh, (r), (x)) #define OREAD4(sc, r) bus_space_read_4((sc)->iot, (sc)->ioh, (r)) #define OREAD2(sc, r) bus_space_read_2((sc)->iot, (sc)->ioh, (r)) -#elif defined(__FreeBSD__) -#define OWRITE4(sc, r, x) *(u_int32_t *) ((sc)->sc_iobase + (r)) = x -#define OREAD4(sc, r) (*(u_int32_t *) ((sc)->sc_iobase + (r))) -#define OREAD2(sc, r) (*(u_int16_t *) ((sc)->sc_iobase + (r))) -#endif /* Reverse the bits in a value 0 .. 31 */ static u_int8_t revbits[OHCI_NO_INTRS] = diff --git a/sys/dev/usb/ohci_pci.c b/sys/dev/usb/ohci_pci.c index 3c20ff723e05..1aea5f1db15d 100644 --- a/sys/dev/usb/ohci_pci.c +++ b/sys/dev/usb/ohci_pci.c @@ -44,6 +44,8 @@ * USB spec: http://www.teleport.com/cgi-bin/mailmerge.cgi/~usb/cgiform.tpl */ +#include "opt_bus.h" + #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> @@ -52,23 +54,13 @@ #include <sys/device.h> #include <sys/proc.h> #include <sys/queue.h> +#include <machine/bus.h> +#include <sys/rman.h> +#include <machine/resource.h> #include <pci/pcivar.h> #include <pci/pcireg.h> -#define PCI_CLASS_SERIALBUS 0x0c000000 -#define PCI_SUBCLASS_COMMUNICATIONS_SERIAL 0x00000000 -#define PCI_SUBCLASS_SERIALBUS_FIREWIRE 0x00000000 -#define PCI_SUBCLASS_SERIALBUS_ACCESS 0x00010000 -#define PCI_SUBCLASS_SERIALBUS_SSA 0x00020000 -#define PCI_SUBCLASS_SERIALBUS_USB 0x00030000 -#define PCI_SUBCLASS_SERIALBUS_FIBER 0x00040000 - -#define PCI_INTERFACE(d) (((d) >> 8) & 0xff) -#define PCI_SUBCLASS(d) ((d) & PCI_SUBCLASS_MASK) -#define PCI_CLASS(d) ((d) & PCI_CLASS_MASK) - - #include <dev/usb/usb.h> #include <dev/usb/usbdi.h> #include <dev/usb/usbdivar.h> @@ -77,7 +69,6 @@ #include <dev/usb/ohcireg.h> #include <dev/usb/ohcivar.h> - #define PCI_OHCI_VENDORID_ALI 0x10b9 #define PCI_OHCI_VENDORID_CMDTECH 0x1095 #define PCI_OHCI_VENDORID_COMPAQ 0x0e11 @@ -98,27 +89,12 @@ static const char *ohci_device_usb0673 = "CMD Tech 673 (USB0673) USB Host Contr static const char *ohci_device_generic = "OHCI (generic) USB Host Controller"; - -static const char *ohci_pci_probe __P((pcici_t, pcidi_t)); -static void ohci_pci_attach __P((pcici_t, int)); - -static u_long ohci_count = 0; - -static struct pci_device ohci_pci_device = { - "ohci", - ohci_pci_probe, - ohci_pci_attach, - &ohci_count, - NULL -}; - -DATA_SET(pcidevice_set, ohci_pci_device); - +#define PCI_OHCI_BASE_REG 0x10 static const char * -ohci_pci_probe(pcici_t config_id, pcidi_t device_id) +ohci_pci_match(device_t dev) { - u_int32_t class; + u_int32_t device_id = pci_get_devid(dev); switch(device_id) { case PCI_OHCI_DEVICEID_ALADDIN_V: @@ -132,54 +108,72 @@ ohci_pci_probe(pcici_t config_id, pcidi_t device_id) case PCI_OHCI_DEVICEID_NEC: return (ohci_device_nec); default: - class = pci_conf_read(config_id, PCI_CLASS_REG); - if ( (PCI_CLASS(class) == PCI_CLASS_SERIALBUS) - && (PCI_SUBCLASS(class) == PCI_SUBCLASS_SERIALBUS_USB) - && (PCI_INTERFACE(class) == PCI_INTERFACE_OHCI)) { - return(ohci_device_generic); + if ( pci_get_class(dev) == PCIC_SERIALBUS + && pci_get_subclass(dev) == PCIS_SERIALBUS_USB + && pci_get_progif(dev) == PCI_INTERFACE_OHCI) { + return (ohci_device_generic); } } return NULL; /* dunno */ } -static void -ohci_pci_attach(pcici_t config_id, int unit) +static int +ohci_pci_probe(device_t dev) { - vm_offset_t pbase; + const char *desc = ohci_pci_match(dev); + if (desc) { + device_set_desc(dev, desc); + return 0; + } else { + return ENXIO; + } +} + +static int +ohci_pci_attach(device_t dev) +{ + int unit = device_get_unit(dev); + ohci_softc_t *sc = device_get_softc(dev); device_t usbus; - ohci_softc_t *sc; usbd_status err; - int id; + int rid; + struct resource *res; + void *ih; + int error; + + rid = PCI_CBMEM; + res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, + 0, ~0, 1, RF_ACTIVE); + if (!res) { + device_printf(dev, "could not map memory\n"); + return ENXIO; + } - sc = malloc(sizeof(ohci_softc_t), M_DEVBUF, M_NOWAIT); - /* Do not free it below, intr might use the sc */ - if ( sc == NULL ) { - printf("ohci%d: could not allocate memory", unit); - return; - } - memset(sc, 0, sizeof(ohci_softc_t)); + sc->iot = rman_get_bustag(res); + sc->ioh = rman_get_bushandle(res); - if(!pci_map_mem(config_id, PCI_CBMEM, - (vm_offset_t *)&sc->sc_iobase, &pbase)) { - printf("ohci%d: could not map memory\n", unit); - return; - } + rid = 0; + res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, + RF_SHAREABLE | RF_ACTIVE); + if (res == NULL) { + device_printf(dev, "could not allocate irq\n"); + return ENOMEM; + } - if ( !pci_map_int(config_id, (pci_inthand_t *)ohci_intr, - (void *) sc, &bio_imask)) { - printf("ohci%d: could not map irq\n", unit); - return; + error = bus_setup_intr(dev, res, (driver_intr_t *) ohci_intr, sc, &ih); + if (error) { + device_printf(dev, "could not setup irq\n"); + return error; } - usbus = device_add_child(root_bus, "usb", -1, sc); + usbus = device_add_child(dev, "usb", -1, sc); if (!usbus) { - printf("ohci%d: could not add USB device to root bus\n", unit); - return; + printf("ohci%d: could not add USB device\n", unit); + return ENOMEM; } - id = pci_conf_read(config_id, PCI_ID_REG); - switch(id) { + switch (pci_get_devid(dev)) { case PCI_OHCI_DEVICEID_ALADDIN_V: device_set_desc(usbus, ohci_device_aladdin_v); sprintf(sc->sc_vendor, "AcerLabs"); @@ -202,7 +196,7 @@ ohci_pci_attach(pcici_t config_id, int unit) break; default: if (bootverbose) - printf("(New OHCI DeviceId=0x%08x)\n", id); + printf("(New OHCI DeviceId=0x%08x)\n", pci_get_devid(dev)); device_set_desc(usbus, ohci_device_generic); sprintf(sc->sc_vendor, "(unknown)"); } @@ -211,8 +205,36 @@ ohci_pci_attach(pcici_t config_id, int unit) err = ohci_init(sc); if (err != USBD_NORMAL_COMPLETION) { printf("ohci%d: init failed, error=%d\n", unit, err); - device_delete_child(root_bus, usbus); + device_delete_child(dev, usbus); } - return; + return device_probe_and_attach(sc->sc_bus.bdev); } + +static device_method_t ohci_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, ohci_pci_probe), + DEVMETHOD(device_attach, ohci_pci_attach), + + /* Bus interface */ + DEVMETHOD(bus_print_child, bus_generic_print_child), + DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource), + DEVMETHOD(bus_release_resource, bus_generic_release_resource), + DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), + DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), + DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), + DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), + + { 0, 0 } +}; + +static driver_t ohci_driver = { + "ohci", + ohci_methods, + DRIVER_TYPE_BIO, + sizeof(ohci_softc_t), +}; + +static devclass_t ohci_devclass; + +DRIVER_MODULE(ohci, pci, ohci_driver, ohci_devclass, 0, 0); diff --git a/sys/dev/usb/ohcivar.h b/sys/dev/usb/ohcivar.h index 90630734648a..b485f50eabe9 100644 --- a/sys/dev/usb/ohcivar.h +++ b/sys/dev/usb/ohcivar.h @@ -72,7 +72,8 @@ typedef struct ohci_softc { /* XXX should keep track of all DMA memory */ #elif defined(__FreeBSD__) - int sc_iobase; + bus_space_tag_t iot; + bus_space_handle_t ioh; #endif /* __FreeBSD__ */ usb_dma_t sc_hccadma; diff --git a/sys/dev/usb/ucom.c b/sys/dev/usb/ucom.c index 07cc3f9b0554..00bb152fe932 100644 --- a/sys/dev/usb/ucom.c +++ b/sys/dev/usb/ucom.c @@ -126,13 +126,8 @@ USB_ATTACH(ucom) static int ucom_detach(device_t self) { - const char *devinfo = device_get_desc(self); - DPRINTF(("%s: disconnected\n", USBDEVNAME(self))); - if (devinfo) { - device_set_desc(self, NULL); - free((void *)devinfo, M_USB); - } + device_set_desc(self, NULL); return 0; } #endif diff --git a/sys/dev/usb/ugen.c b/sys/dev/usb/ugen.c index cbd9e1ea71e7..cc14a7df0180 100644 --- a/sys/dev/usb/ugen.c +++ b/sys/dev/usb/ugen.c @@ -992,13 +992,8 @@ ugenpoll(dev, events, p) static int ugen_detach(device_t self) { - const char *devinfo = device_get_desc(self); - DPRINTF(("%s: disconnected\n", USBDEVNAME(self))); - if (devinfo) { - device_set_desc(self, NULL); - free((void *)devinfo, M_USB); - } + device_set_desc(self, NULL); return 0; } diff --git a/sys/dev/usb/uhci.c b/sys/dev/usb/uhci.c index 30c69fd3341c..62cb1068db11 100644 --- a/sys/dev/usb/uhci.c +++ b/sys/dev/usb/uhci.c @@ -63,6 +63,9 @@ cgiform.tpl #include <sys/queue.h> #include <sys/select.h> +#if defined(__FreeBSD__) +#include <machine/bus_pio.h> +#endif #include <machine/bus.h> #include <dev/usb/usb.h> @@ -225,11 +228,11 @@ void uhci_dump_td __P((uhci_soft_td_t *)); #define UREAD2(sc, r) bus_space_read_2((sc)->iot, (sc)->ioh, (r)) #define UREAD4(sc, r) bus_space_read_4((sc)->iot, (sc)->ioh, (r)) #elif defined(__FreeBSD__) -#define UWRITE2(sc,r,x) outw((sc)->sc_iobase + (r), (x)) -#define UWRITE4(sc,r,x) outl((sc)->sc_iobase + (r), (x)) -#define UREAD1(sc,r) inb((sc)->sc_iobase + (r)) -#define UREAD2(sc,r) inw((sc)->sc_iobase + (r)) -#define UREAD4(sc,r) inl((sc)->sc_iobase + (r)) +#define UWRITE2(sc, r, x) bus_space_write_2((sc)->iot, (sc)->ioh, (r), (x)) +#define UWRITE4(sc, r, x) bus_space_write_4((sc)->iot, (sc)->ioh, (r), (x)) +#define UREAD1(sc, r) bus_space_read_1((sc)->iot, (sc)->ioh, (r)) +#define UREAD2(sc, r) bus_space_read_2((sc)->iot, (sc)->ioh, (r)) +#define UREAD4(sc, r) bus_space_read_4((sc)->iot, (sc)->ioh, (r)) #endif #define UHCICMD(sc, cmd) UWRITE2(sc, UHCI_CMD, cmd) diff --git a/sys/dev/usb/uhci_pci.c b/sys/dev/usb/uhci_pci.c index 6ed3cee0381f..4bddf8b32786 100644 --- a/sys/dev/usb/uhci_pci.c +++ b/sys/dev/usb/uhci_pci.c @@ -1,4 +1,4 @@ -/* FreeBSD $Id: uhci_pci.c,v 1.4 1999/04/06 23:09:58 n_hibma Exp $ */ +/* FreeBSD $Id: uhci_pci.c,v 1.5 1999/04/11 14:24:20 n_hibma Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -37,6 +37,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include "opt_bus.h" + #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> @@ -45,23 +47,13 @@ #include <sys/device.h> #include <sys/proc.h> #include <sys/queue.h> +#include <machine/bus.h> +#include <sys/rman.h> +#include <machine/resource.h> #include <pci/pcivar.h> #include <pci/pcireg.h> -#define PCI_CLASS_SERIALBUS 0x0c000000 -#define PCI_SUBCLASS_COMMUNICATIONS_SERIAL 0x00000000 -#define PCI_SUBCLASS_SERIALBUS_FIREWIRE 0x00000000 -#define PCI_SUBCLASS_SERIALBUS_ACCESS 0x00010000 -#define PCI_SUBCLASS_SERIALBUS_SSA 0x00020000 -#define PCI_SUBCLASS_SERIALBUS_USB 0x00030000 -#define PCI_SUBCLASS_SERIALBUS_FIBER 0x00040000 - -#define PCI_INTERFACE(d) (((d)>>8)&0xff) -#define PCI_SUBCLASS(d) ((d)&PCI_SUBCLASS_MASK) -#define PCI_CLASS(d) ((d)&PCI_CLASS_MASK) - - #include <dev/usb/usb.h> #include <dev/usb/usbdi.h> #include <dev/usb/usbdivar.h> @@ -70,7 +62,6 @@ #include <dev/usb/uhcireg.h> #include <dev/usb/uhcivar.h> - #define PCI_UHCI_VENDORID_INTEL 0x8086 #define PCI_UHCI_VENDORID_VIA 0x1106 @@ -85,26 +76,10 @@ static const char *uhci_device_generic = "UHCI (generic) USB Controller"; #define PCI_UHCI_BASE_REG 0x20 -static const char *uhci_pci_probe __P((pcici_t, pcidi_t)); -static void uhci_pci_attach __P((pcici_t, int)); - -static u_long uhci_count = 0; - -static struct pci_device uhci_pci_device = { - "uhci", - uhci_pci_probe, - uhci_pci_attach, - &uhci_count, - NULL -}; - -DATA_SET(pcidevice_set, uhci_pci_device); - - static const char * -uhci_pci_probe(pcici_t config_id, pcidi_t device_id) +uhci_pci_match(device_t dev) { - u_int32_t class; + u_int32_t device_id = pci_get_devid(dev); if (device_id == PCI_UHCI_DEVICEID_PIIX3) { return (uhci_device_piix3); @@ -113,10 +88,9 @@ uhci_pci_probe(pcici_t config_id, pcidi_t device_id) } else if (device_id == PCI_UHCI_DEVICEID_VT83C572) { return (uhci_device_vt83c572); } else { - class = pci_conf_read(config_id, PCI_CLASS_REG); - if ( PCI_CLASS(class) == PCI_CLASS_SERIALBUS - && PCI_SUBCLASS(class) == PCI_SUBCLASS_SERIALBUS_USB - && PCI_INTERFACE(class) == PCI_INTERFACE_UHCI) { + if ( pci_get_class(dev) == PCIC_SERIALBUS + && pci_get_subclass(dev) == PCIS_SERIALBUS_USB + && pci_get_progif(dev) == PCI_INTERFACE_UHCI) { return (uhci_device_generic); } } @@ -124,42 +98,64 @@ uhci_pci_probe(pcici_t config_id, pcidi_t device_id) return NULL; /* dunno... */ } -static void -uhci_pci_attach(pcici_t config_id, int unit) +static int +uhci_pci_probe(device_t dev) +{ + const char *desc = uhci_pci_match(dev); + if (desc) { + device_set_desc(dev, desc); + return 0; + } else { + return ENXIO; + } +} + +static int +uhci_pci_attach(device_t dev) { - int id, legsup; + int unit = device_get_unit(dev); + int legsup; char *typestr; usbd_status err; - uhci_softc_t *sc = NULL; device_t usbus; - - sc = malloc(sizeof(uhci_softc_t), M_DEVBUF, M_NOWAIT); - /* Do not free it below, intr might use the sc */ - if ( sc == NULL ) { - printf("uhci%d: could not allocate memory", unit); - return; + uhci_softc_t *sc = device_get_softc(dev); + int rid; + struct resource *res; + void *ih; + int error; + + rid = PCI_UHCI_BASE_REG; + res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, + 0, ~0, 1, RF_ACTIVE); + if (!res) { + device_printf(dev, "could not map ports\n"); + return ENXIO; + } + + sc->iot = rman_get_bustag(res); + sc->ioh = rman_get_bushandle(res); + + rid = 0; + res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, + RF_SHAREABLE | RF_ACTIVE); + if (res == NULL) { + device_printf(dev, "could not allocate irq\n"); + return ENOMEM; } - memset(sc, 0, sizeof(uhci_softc_t)); - - if ( !pci_map_port(config_id, PCI_UHCI_BASE_REG, &sc->sc_iobase) ) { - printf("uhci%d: could not map port\n", unit); - return; - } - - if ( !pci_map_int(config_id, (pci_inthand_t *)uhci_intr, - (void *) sc, &bio_imask)) { - printf("uhci%d: could not map irq\n", unit); - return; + + error = bus_setup_intr(dev, res, (driver_intr_t *) uhci_intr, sc, &ih); + if (error) { + device_printf(dev, "could not setup irq\n"); + return error; } - usbus = device_add_child(root_bus, "usb", -1, sc); + usbus = device_add_child(dev, "usb", -1, sc); if (!usbus) { - printf("usb%d: could not add USB device to root bus\n", unit); - return; + printf("usb%d: could not add USB device\n", unit); + return ENOMEM; } - id = pci_conf_read(config_id, PCI_ID_REG); - switch (id) { + switch (pci_get_devid(dev)) { case PCI_UHCI_DEVICEID_PIIX3: device_set_desc(usbus, uhci_device_piix3); sprintf(sc->sc_vendor, "Intel"); @@ -173,13 +169,13 @@ uhci_pci_attach(pcici_t config_id, int unit) sprintf(sc->sc_vendor, "VIA"); break; default: - printf("(New UHCI DeviceId=0x%08x)\n", id); + printf("(New UHCI DeviceId=0x%08x)\n", pci_get_devid(dev)); device_set_desc(usbus, uhci_device_generic); - sprintf(sc->sc_vendor, "(0x%08x)", id); + sprintf(sc->sc_vendor, "(0x%08x)", pci_get_devid(dev)); } if (bootverbose) { - switch(pci_conf_read(config_id, PCI_USBREV) & PCI_USBREV_MASK) { + switch(pci_read_config(dev, PCI_USBREV, 4) & PCI_USBREV_MASK) { case PCI_USBREV_PRE_1_0: typestr = "pre 1.0"; break; @@ -191,25 +187,53 @@ uhci_pci_attach(pcici_t config_id, int unit) break; } printf("uhci%d: USB version %s, chip rev. %d\n", unit, typestr, - (int) pci_conf_read(config_id, PCIR_REVID) & 0xff); + pci_get_revid(dev)); } - legsup = pci_conf_read(config_id, PCI_LEGSUP); + legsup = pci_read_config(dev, PCI_LEGSUP, 4); if ( !(legsup & PCI_LEGSUP_USBPIRQDEN) ) { #if ! (defined(USBVERBOSE) || defined(USB_DEBUG)) if (bootverbose) #endif printf("uhci%d: PIRQD enable not set\n", unit); legsup |= PCI_LEGSUP_USBPIRQDEN; - pci_conf_write(config_id, PCI_LEGSUP, legsup); + pci_write_config(dev, PCI_LEGSUP, legsup, 4); } sc->sc_bus.bdev = usbus; err = uhci_init(sc); if (err != USBD_NORMAL_COMPLETION) { printf("uhci%d: init failed, error=%d\n", unit, err); - device_delete_child(root_bus, usbus); + device_delete_child(dev, usbus); } - return; + return device_probe_and_attach(sc->sc_bus.bdev); } + +static device_method_t uhci_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, uhci_pci_probe), + DEVMETHOD(device_attach, uhci_pci_attach), + + /* Bus interface */ + DEVMETHOD(bus_print_child, bus_generic_print_child), + DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource), + DEVMETHOD(bus_release_resource, bus_generic_release_resource), + DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), + DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), + DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), + DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), + + { 0, 0 } +}; + +static driver_t uhci_driver = { + "uhci", + uhci_methods, + DRIVER_TYPE_BIO, + sizeof(uhci_softc_t), +}; + +static devclass_t uhci_devclass; + +DRIVER_MODULE(uhci, pci, uhci_driver, uhci_devclass, 0, 0); diff --git a/sys/dev/usb/uhcivar.h b/sys/dev/usb/uhcivar.h index 2171374546bc..89fed85c6b35 100644 --- a/sys/dev/usb/uhcivar.h +++ b/sys/dev/usb/uhcivar.h @@ -125,7 +125,8 @@ typedef struct uhci_softc { bus_dma_tag_t sc_dmatag; /* DMA tag */ /* XXX should keep track of all DMA memory */ #elif defined(__FreeBSD__) - int sc_iobase; + bus_space_tag_t iot; + bus_space_handle_t ioh; #endif /* defined(__FreeBSD__) */ uhci_physaddr_t *sc_pframes; diff --git a/sys/dev/usb/uhid.c b/sys/dev/usb/uhid.c index a55944bdd0fc..e43455630d68 100644 --- a/sys/dev/usb/uhid.c +++ b/sys/dev/usb/uhid.c @@ -200,13 +200,8 @@ USB_ATTACH(uhid) static int uhid_detach(device_t self) { - const char *devinfo = device_get_desc(self); - DPRINTF(("%s: disconnected\n", USBDEVNAME(self))); - if (devinfo) { - device_set_desc(self, NULL); - free((void *)devinfo, M_USB); - } + device_set_desc(self, NULL); return 0; } #endif diff --git a/sys/dev/usb/uhub.c b/sys/dev/usb/uhub.c index 2f4029cf7b43..bf53c016fbb3 100644 --- a/sys/dev/usb/uhub.c +++ b/sys/dev/usb/uhub.c @@ -81,10 +81,15 @@ usbd_status uhub_init_port __P((struct usbd_port *)); void uhub_disconnect_port __P((struct usbd_port *up)); usbd_status uhub_explore __P((usbd_device_handle hub)); void uhub_intr __P((usbd_request_handle, usbd_private_handle, usbd_status)); +#ifdef __FreeBSD__ +#include "usb_if.h" +static void uhub_disconnected __P((device_t)); +#endif /* void uhub_disco __P((void *)); */ -USB_DECLARE_DRIVER(uhub); +USB_DECLARE_DRIVER_INIT(uhub, + DEVMETHOD(usb_disconnected, uhub_disconnected)); #if defined(__FreeBSD__) devclass_t uhubroot_devclass; @@ -251,8 +256,8 @@ USB_ATTACH(uhub) } #if defined(__FreeBSD__) -static int -uhub_detach(device_t self) +static void +uhub_disconnected(device_t self) { struct uhub_softc *sc = device_get_softc(self); struct usbd_port *up; @@ -264,12 +269,20 @@ uhub_detach(device_t self) nports = dev->hub->hubdesc.bNbrPorts; for (p = 0; p < nports; p++) { up = &sc->sc_hub->hub->ports[p]; - if (up->device) + if (up->device) { uhub_disconnect_port(up); + } } - free(sc->sc_hub->hub, M_USB); + return; +} +static int +uhub_detach(device_t self) +{ + struct uhub_softc *sc = device_get_softc(self); + DPRINTF(("%s: disconnected\n", USBDEVNAME(self))); + free(sc->sc_hub->hub, M_USB); return 0; } #endif @@ -502,6 +515,7 @@ uhub_disconnect_port(up) } } #if defined(__FreeBSD__) + USB_DISCONNECTED(sc->sc_dev); device_delete_child(scp->sc_dev, sc->sc_dev); #endif diff --git a/sys/dev/usb/ulpt.c b/sys/dev/usb/ulpt.c index 098446036eb4..9aaf02478279 100644 --- a/sys/dev/usb/ulpt.c +++ b/sys/dev/usb/ulpt.c @@ -437,13 +437,8 @@ ulptioctl(dev, cmd, data, flag, p) static int ulpt_detach(device_t self) { - const char *devinfo = device_get_desc(self); - DPRINTF(("%s: disconnected\n", USBDEVNAME(self))); - if (devinfo) { - device_set_desc(self, NULL); - free((void *)devinfo, M_USB); - } + device_set_desc(self, NULL); return 0; } diff --git a/sys/dev/usb/umodem.c b/sys/dev/usb/umodem.c index 7a1b6007b63f..c624b8667d98 100644 --- a/sys/dev/usb/umodem.c +++ b/sys/dev/usb/umodem.c @@ -125,13 +125,8 @@ USB_ATTACH(umodem) static int umodem_detach(device_t self) { - const char *devinfo = device_get_desc(self); - DPRINTF(("%s: disconnected\n", USBDEVNAME(self))); - if (devinfo) { - device_set_desc(self, NULL); - free((void *)devinfo, M_USB); - } + device_set_desc(self, NULL); return 0; } diff --git a/sys/dev/usb/ums.c b/sys/dev/usb/ums.c index 946456632519..4d3578b7655c 100644 --- a/sys/dev/usb/ums.c +++ b/sys/dev/usb/ums.c @@ -363,7 +363,6 @@ static int ums_detach(device_t self) { struct ums_softc *sc = device_get_softc(self); - const char *devinfo = device_get_desc(self); if (sc->sc_enabled) { usbd_abort_pipe(sc->sc_intrpipe); @@ -372,10 +371,7 @@ ums_detach(device_t self) sc->sc_disconnected = 1; DPRINTF(("%s: disconnected\n", USBDEVNAME(self))); - if (devinfo) { - device_set_desc(self, NULL); - free((void *)devinfo, M_USB); - } + device_set_desc(self, NULL); free(sc->sc_loc_btn, M_USB); free(sc->sc_ibuf, M_USB); diff --git a/sys/dev/usb/usb.c b/sys/dev/usb/usb.c index 935f951f1ee5..8d9689ad1e8f 100644 --- a/sys/dev/usb/usb.c +++ b/sys/dev/usb/usb.c @@ -408,5 +408,6 @@ usb_detach(device_t self) return (1); } -DRIVER_MODULE(usb, root, usb_driver, usb_devclass, 0, 0); +DRIVER_MODULE(usb, uhci, usb_driver, usb_devclass, 0, 0); +DRIVER_MODULE(usb, ohci, usb_driver, usb_devclass, 0, 0); #endif diff --git a/sys/dev/usb/usb_if.m b/sys/dev/usb/usb_if.m index 2c5e52194dbf..62ea1186337d 100644 --- a/sys/dev/usb/usb_if.m +++ b/sys/dev/usb/usb_if.m @@ -25,7 +25,7 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -# $Id: usb_if.m,v 1.3 1999/01/07 23:31:37 n_hibma Exp $ +# $Id: usb_if.m,v 1.4 1999/03/22 19:58:59 n_hibma Exp $ # # USB interface description @@ -38,3 +38,10 @@ INTERFACE usb; METHOD int reconfigure { device_t dev; }; + +# The device is being disconnected and should clean up before +# being destroyed. +# +METHOD void disconnected { + device_t dev; +}; diff --git a/sys/dev/usb/usb_port.h b/sys/dev/usb/usb_port.h index f1dd74ae80e9..ea144b9beac1 100644 --- a/sys/dev/usb/usb_port.h +++ b/sys/dev/usb/usb_port.h @@ -126,7 +126,7 @@ __CONCAT(dname,_attach)(parent, self, aux) \ * because of includes in the wrong order. */ #define bdevice device_t -#define USBDEVNAME(bdev) usbd_devname(&bdev) +#define USBDEVNAME(bdev) device_get_nameunit(bdev) /* XXX Change this when FreeBSD has memset */ diff --git a/sys/dev/usb/usbdi.c b/sys/dev/usb/usbdi.c index d045a4d6b34a..8b88cd3312c3 100644 --- a/sys/dev/usb/usbdi.c +++ b/sys/dev/usb/usbdi.c @@ -1302,30 +1302,7 @@ usbd_driver_load(module_t mod, int what, void *arg) void usbd_device_set_desc(device_t device, char *devinfo) { - size_t l; - char *desc; - - if ( devinfo ) { - l = strlen(devinfo); - desc = malloc(l+1, M_USB, M_NOWAIT); - if (desc) - memcpy(desc, devinfo, l+1); - } else - desc = NULL; - - device_set_desc(device, desc); -} - -char * -usbd_devname(bdevice *bdev) -{ - static char buf[20]; - /* XXX a static buffer is not exactly a good idea, but the only - * thing that goes wrong is the string that is being printed - */ - - sprintf(buf, "%s%d", device_get_name(*bdev), device_get_unit(*bdev)); - return (buf); + device_set_desc_copy(device, devinfo); } #endif diff --git a/sys/dev/usb/usbdi.h b/sys/dev/usb/usbdi.h index 8cdcfdbe3d6b..7a41f8bd42d9 100644 --- a/sys/dev/usb/usbdi.h +++ b/sys/dev/usb/usbdi.h @@ -336,7 +336,6 @@ usb_endpoint_descriptor_t *usbd_get_endpoint_descriptor #if defined(__FreeBSD__) int usbd_driver_load __P((module_t mod, int what, void *arg)); void usbd_device_set_desc __P((device_t device, char *devinfo)); -char *usbd_devname(bdevice *bdev); bus_print_child_t usbd_print_child; #endif |