118334Speter/*- 250397Sobrien * Copyright (c) 2004 TAKAHASHI Yoshihiro 318334Speter * All rights reserved. 418334Speter * 518334Speter * Redistribution and use in source and binary forms, with or without 618334Speter * modification, are permitted provided that the following conditions 718334Speter * are met: 818334Speter * 1. Redistributions of source code must retain the above copyright 918334Speter * notice, this list of conditions, and the following disclaimer, 1018334Speter * without modification, immediately at the beginning of the file. 1118334Speter * 2. Redistributions in binary form must reproduce the above copyright 1218334Speter * notice, this list of conditions and the following disclaimer in 1318334Speter * the documentation and/or other materials provided with the 1418334Speter * distribution. 1518334Speter * 1618334Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1718334Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1818334Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1918334Speter * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 2018334Speter * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2118334Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2250397Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2318334Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2418334Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2550397Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2618334Speter * SUCH DAMAGE. 2718334Speter */ 2818334Speter 2918334Speter#include <sys/cdefs.h> 3018334Speter__FBSDID("$FreeBSD: releng/10.3/sys/pc98/cbus/fdc_cbus.c 146216 2005-05-14 10:51:16Z nyan $"); 3150397Sobrien 3250397Sobrien#include <sys/param.h> 3350397Sobrien#include <sys/bio.h> 3418334Speter#include <sys/bus.h> 3550397Sobrien#include <sys/kernel.h> 3618334Speter#include <sys/module.h> 3718334Speter#include <sys/rman.h> 3818334Speter#include <sys/systm.h> 3918334Speter 4018334Speter#include <machine/bus.h> 4118334Speter 4218334Speter#include <pc98/cbus/cbus.h> 4318334Speter#include <pc98/cbus/fdcreg.h> 4418334Speter#include <pc98/cbus/fdcvar.h> 4518334Speter 4618334Speter#include <isa/isavar.h> 4718334Speter 4850397Sobrienstatic bus_addr_t fdc_iat[] = {0, 2, 4}; 4950397Sobrien 5050397Sobrienstatic int 5150397Sobrienfdc_cbus_alloc_resources(device_t dev, struct fdc_data *fdc) 5250397Sobrien{ 5350397Sobrien int rid; 5450397Sobrien 5550397Sobrien fdc->fdc_dev = dev; 5650397Sobrien fdc->rid_ioport = 0; 5750397Sobrien fdc->rid_irq = 0; 5850397Sobrien fdc->rid_drq = 0; 5950397Sobrien fdc->res_irq = 0; 6050397Sobrien fdc->res_drq = 0; 6118334Speter 6250397Sobrien fdc->res_ioport = isa_alloc_resourcev(dev, SYS_RES_IOPORT, 6350397Sobrien &fdc->rid_ioport, fdc_iat, 6450397Sobrien 3, RF_ACTIVE); 6518334Speter if (fdc->res_ioport == 0) { 6618334Speter device_printf(dev, "cannot reserve I/O port range\n"); 6718334Speter return ENXIO; 6818334Speter } 6950397Sobrien isa_load_resourcev(fdc->res_ioport, fdc_iat, 3); 7018334Speter fdc->portt = rman_get_bustag(fdc->res_ioport); 7118334Speter fdc->porth = rman_get_bushandle(fdc->res_ioport); 7218334Speter 7318334Speter rid = 3; 7418334Speter bus_set_resource(dev, SYS_RES_IOPORT, rid, IO_FDPORT, 1); 7518334Speter fdc->res_fdsio = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, 7618334Speter RF_ACTIVE); 7750397Sobrien if (fdc->res_fdsio == 0) 7818334Speter return ENXIO; 7918334Speter fdc->sc_fdsiot = rman_get_bustag(fdc->res_fdsio); 8018334Speter fdc->sc_fdsioh = rman_get_bushandle(fdc->res_fdsio); 8118334Speter 8218334Speter rid = 4; 8318334Speter bus_set_resource(dev, SYS_RES_IOPORT, rid, 0x4be, 1); 8418334Speter fdc->res_fdemsio = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, 8518334Speter RF_ACTIVE); 8618334Speter if (fdc->res_fdemsio == 0) 8718334Speter return ENXIO; 8818334Speter fdc->sc_fdemsiot = rman_get_bustag(fdc->res_fdemsio); 8918334Speter fdc->sc_fdemsioh = rman_get_bushandle(fdc->res_fdemsio); 9018334Speter 9118334Speter fdc->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &fdc->rid_irq, 9218334Speter RF_ACTIVE); 9318334Speter if (fdc->res_irq == 0) { 9418334Speter device_printf(dev, "cannot reserve interrupt line\n"); 9518334Speter return ENXIO; 9618334Speter } 9718334Speter 9818334Speter if ((fdc->flags & FDC_NODMA) == 0) { 9918334Speter fdc->res_drq = bus_alloc_resource_any(dev, SYS_RES_DRQ, 10018334Speter &fdc->rid_drq, RF_ACTIVE); 10118334Speter if (fdc->res_drq == 0) { 10218334Speter device_printf(dev, "cannot reserve DMA request line\n"); 10318334Speter return ENXIO; 10418334Speter } 10518334Speter fdc->dmachan = rman_get_start(fdc->res_drq); 10618334Speter } 10718334Speter 10818334Speter return 0; 10918334Speter} 11018334Speter 11118334Speterstatic int 11218334Speterfdc_cbus_probe(device_t dev) 11318334Speter{ 11418334Speter int error; 11518334Speter struct fdc_data *fdc; 11618334Speter 11718334Speter fdc = device_get_softc(dev); 11818334Speter 11918334Speter /* Check pnp ids */ 12018334Speter if (isa_get_vendorid(dev)) 12118334Speter return (ENXIO); 12218334Speter 12318334Speter /* Attempt to allocate our resources for the duration of the probe */ 12418334Speter error = fdc_cbus_alloc_resources(dev, fdc); 12550397Sobrien if (!error) 12618334Speter error = fdc_initial_reset(fdc); 12718334Speter 12818334Speter fdc_release_resources(fdc); 12918334Speter return (error); 13018334Speter} 13118334Speter 13218334Speterstatic int 13318334Speterfdc_cbus_attach(device_t dev) 13418334Speter{ 13518334Speter struct fdc_data *fdc; 13618334Speter int error; 13718334Speter 13818334Speter fdc = device_get_softc(dev); 13950397Sobrien 14050397Sobrien if ((error = fdc_cbus_alloc_resources(dev, fdc)) != 0 || 14118334Speter (error = fdc_attach(dev)) != 0 || 14218334Speter (error = fdc_hints_probe(dev)) != 0) { 14318334Speter fdc_release_resources(fdc); 14418334Speter return (error); 14518334Speter } 14618334Speter 14718334Speter return (0); 14818334Speter} 14918334Speter 15018334Speterstatic device_method_t fdc_methods[] = { 15118334Speter /* Device interface */ 15218334Speter DEVMETHOD(device_probe, fdc_cbus_probe), 15318334Speter DEVMETHOD(device_attach, fdc_cbus_attach), 15418334Speter DEVMETHOD(device_detach, fdc_detach), 15518334Speter DEVMETHOD(device_shutdown, bus_generic_shutdown), 15618334Speter DEVMETHOD(device_suspend, bus_generic_suspend), 15718334Speter DEVMETHOD(device_resume, bus_generic_resume), 15818334Speter 15918334Speter /* Bus interface */ 16050397Sobrien DEVMETHOD(bus_print_child, fdc_print_child), 16118334Speter DEVMETHOD(bus_read_ivar, fdc_read_ivar), 16250397Sobrien DEVMETHOD(bus_write_ivar, fdc_write_ivar), 16350397Sobrien /* Our children never use any other bus interface methods. */ 16418334Speter 16518334Speter { 0, 0 } 16618334Speter}; 16718334Speter 16818334Speterstatic driver_t fdc_driver = { 16950397Sobrien "fdc", 17050397Sobrien fdc_methods, 17118334Speter sizeof(struct fdc_data) 17218334Speter}; 17318334Speter 17418334SpeterDRIVER_MODULE(fdc, isa, fdc_driver, fdc_devclass, 0, 0); 17518334Speter