164220a7eSMarcel Moolenaar /*- 264220a7eSMarcel Moolenaar * Copyright (c) 2006 Marcel Moolenaar 364220a7eSMarcel Moolenaar * All rights reserved. 464220a7eSMarcel Moolenaar * 564220a7eSMarcel Moolenaar * Redistribution and use in source and binary forms, with or without 664220a7eSMarcel Moolenaar * modification, are permitted provided that the following conditions 764220a7eSMarcel Moolenaar * are met: 864220a7eSMarcel Moolenaar * 964220a7eSMarcel Moolenaar * 1. Redistributions of source code must retain the above copyright 1064220a7eSMarcel Moolenaar * notice, this list of conditions and the following disclaimer. 1164220a7eSMarcel Moolenaar * 2. Redistributions in binary form must reproduce the above copyright 1264220a7eSMarcel Moolenaar * notice, this list of conditions and the following disclaimer in the 1364220a7eSMarcel Moolenaar * documentation and/or other materials provided with the distribution. 1464220a7eSMarcel Moolenaar * 1564220a7eSMarcel Moolenaar * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1664220a7eSMarcel Moolenaar * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1764220a7eSMarcel Moolenaar * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1864220a7eSMarcel Moolenaar * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 1964220a7eSMarcel Moolenaar * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2064220a7eSMarcel Moolenaar * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2164220a7eSMarcel Moolenaar * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2264220a7eSMarcel Moolenaar * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2364220a7eSMarcel Moolenaar * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2464220a7eSMarcel Moolenaar * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2564220a7eSMarcel Moolenaar */ 2664220a7eSMarcel Moolenaar 2764220a7eSMarcel Moolenaar #include <sys/cdefs.h> 2864220a7eSMarcel Moolenaar __FBSDID("$FreeBSD$"); 2964220a7eSMarcel Moolenaar 3064220a7eSMarcel Moolenaar #include <sys/param.h> 3164220a7eSMarcel Moolenaar #include <sys/systm.h> 3264220a7eSMarcel Moolenaar #include <sys/bus.h> 3364220a7eSMarcel Moolenaar #include <sys/rman.h> 3464220a7eSMarcel Moolenaar 3564220a7eSMarcel Moolenaar #include <dev/puc/puc_bfe.h> 3664220a7eSMarcel Moolenaar #include <dev/puc/puc_bus.h> 3764220a7eSMarcel Moolenaar #include <dev/puc/puc_cfg.h> 3864220a7eSMarcel Moolenaar 3964220a7eSMarcel Moolenaar int 4064220a7eSMarcel Moolenaar puc_config(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port, intptr_t *r) 4164220a7eSMarcel Moolenaar { 4264220a7eSMarcel Moolenaar const struct puc_cfg *cfg = sc->sc_cfg; 4364220a7eSMarcel Moolenaar int error; 4464220a7eSMarcel Moolenaar 4564220a7eSMarcel Moolenaar if (cfg->config_function != NULL) { 4664220a7eSMarcel Moolenaar error = cfg->config_function(sc, cmd, port, r); 4764220a7eSMarcel Moolenaar if (!error) 4864220a7eSMarcel Moolenaar return (0); 4964220a7eSMarcel Moolenaar } else 5064220a7eSMarcel Moolenaar error = EDOOFUS; 5164220a7eSMarcel Moolenaar 5264220a7eSMarcel Moolenaar switch (cmd) { 5364220a7eSMarcel Moolenaar case PUC_CFG_GET_CLOCK: 5464220a7eSMarcel Moolenaar if (cfg->clock < 0) 5564220a7eSMarcel Moolenaar return (error); 5664220a7eSMarcel Moolenaar *r = cfg->clock; 5764220a7eSMarcel Moolenaar return (0); 5864220a7eSMarcel Moolenaar case PUC_CFG_GET_DESC: 5964220a7eSMarcel Moolenaar if (cfg->desc == NULL) 6064220a7eSMarcel Moolenaar return (error); 6164220a7eSMarcel Moolenaar *r = (intptr_t)cfg->desc; 6264220a7eSMarcel Moolenaar return (0); 6364220a7eSMarcel Moolenaar case PUC_CFG_GET_ILR: 6464220a7eSMarcel Moolenaar *r = PUC_ILR_NONE; 6564220a7eSMarcel Moolenaar return (0); 6664220a7eSMarcel Moolenaar case PUC_CFG_GET_LEN: 6764220a7eSMarcel Moolenaar /* The length of bus space needed by the port. */ 6864220a7eSMarcel Moolenaar *r = 8; 6964220a7eSMarcel Moolenaar return (0); 7064220a7eSMarcel Moolenaar case PUC_CFG_GET_NPORTS: 7164220a7eSMarcel Moolenaar /* The number of ports on this card. */ 7264220a7eSMarcel Moolenaar switch (cfg->ports) { 7364220a7eSMarcel Moolenaar case PUC_PORT_NONSTANDARD: 7464220a7eSMarcel Moolenaar return (error); 7564220a7eSMarcel Moolenaar case PUC_PORT_1P: 7664220a7eSMarcel Moolenaar case PUC_PORT_1S: 7764220a7eSMarcel Moolenaar *r = 1; 7864220a7eSMarcel Moolenaar return (0); 7964220a7eSMarcel Moolenaar case PUC_PORT_1S1P: 8064220a7eSMarcel Moolenaar case PUC_PORT_2P: 8164220a7eSMarcel Moolenaar case PUC_PORT_2S: 8264220a7eSMarcel Moolenaar *r = 2; 8364220a7eSMarcel Moolenaar return (0); 8464220a7eSMarcel Moolenaar case PUC_PORT_1S2P: 8564220a7eSMarcel Moolenaar case PUC_PORT_2S1P: 8664220a7eSMarcel Moolenaar case PUC_PORT_3S: 8764220a7eSMarcel Moolenaar *r = 3; 8864220a7eSMarcel Moolenaar return (0); 8964220a7eSMarcel Moolenaar case PUC_PORT_4S: 9064220a7eSMarcel Moolenaar *r = 4; 9164220a7eSMarcel Moolenaar return (0); 9264220a7eSMarcel Moolenaar case PUC_PORT_4S1P: 9364220a7eSMarcel Moolenaar *r = 5; 9464220a7eSMarcel Moolenaar return (0); 9564220a7eSMarcel Moolenaar case PUC_PORT_6S: 9664220a7eSMarcel Moolenaar *r = 6; 9764220a7eSMarcel Moolenaar return (0); 9864220a7eSMarcel Moolenaar case PUC_PORT_8S: 9964220a7eSMarcel Moolenaar *r = 8; 10064220a7eSMarcel Moolenaar return (0); 10164220a7eSMarcel Moolenaar case PUC_PORT_12S: 10264220a7eSMarcel Moolenaar *r = 12; 10364220a7eSMarcel Moolenaar return (0); 10464220a7eSMarcel Moolenaar case PUC_PORT_16S: 10564220a7eSMarcel Moolenaar *r = 16; 10664220a7eSMarcel Moolenaar return (0); 10764220a7eSMarcel Moolenaar } 10864220a7eSMarcel Moolenaar break; 10964220a7eSMarcel Moolenaar case PUC_CFG_GET_OFS: 11064220a7eSMarcel Moolenaar /* The offset relative to the RID. */ 11164220a7eSMarcel Moolenaar if (cfg->d_ofs < 0) 11264220a7eSMarcel Moolenaar return (error); 11364220a7eSMarcel Moolenaar *r = port * cfg->d_ofs; 11464220a7eSMarcel Moolenaar return (0); 11564220a7eSMarcel Moolenaar case PUC_CFG_GET_RID: 11664220a7eSMarcel Moolenaar /* The RID for this port. */ 11764220a7eSMarcel Moolenaar if (port == 0) { 11864220a7eSMarcel Moolenaar if (cfg->rid < 0) 11964220a7eSMarcel Moolenaar return (error); 12064220a7eSMarcel Moolenaar *r = cfg->rid; 12164220a7eSMarcel Moolenaar return (0); 12264220a7eSMarcel Moolenaar } 12364220a7eSMarcel Moolenaar if (cfg->d_rid < 0) 12464220a7eSMarcel Moolenaar return (error); 12564220a7eSMarcel Moolenaar if (cfg->rid < 0) { 12664220a7eSMarcel Moolenaar error = puc_config(sc, PUC_CFG_GET_RID, 0, r); 12764220a7eSMarcel Moolenaar if (error) 12864220a7eSMarcel Moolenaar return (error); 12964220a7eSMarcel Moolenaar } else 13064220a7eSMarcel Moolenaar *r = cfg->rid; 13164220a7eSMarcel Moolenaar *r += port * cfg->d_rid; 13264220a7eSMarcel Moolenaar return (0); 13364220a7eSMarcel Moolenaar case PUC_CFG_GET_TYPE: 13464220a7eSMarcel Moolenaar /* The type of this port. */ 13564220a7eSMarcel Moolenaar if (cfg->ports == PUC_PORT_NONSTANDARD) 13664220a7eSMarcel Moolenaar return (error); 13764220a7eSMarcel Moolenaar switch (port) { 13864220a7eSMarcel Moolenaar case 0: 13964220a7eSMarcel Moolenaar if (cfg->ports == PUC_PORT_1P || 14064220a7eSMarcel Moolenaar cfg->ports == PUC_PORT_2P) 14164220a7eSMarcel Moolenaar *r = PUC_TYPE_PARALLEL; 14264220a7eSMarcel Moolenaar else 14364220a7eSMarcel Moolenaar *r = PUC_TYPE_SERIAL; 14464220a7eSMarcel Moolenaar return (0); 14564220a7eSMarcel Moolenaar case 1: 14664220a7eSMarcel Moolenaar if (cfg->ports == PUC_PORT_1S1P || 14764220a7eSMarcel Moolenaar cfg->ports == PUC_PORT_1S2P || 14864220a7eSMarcel Moolenaar cfg->ports == PUC_PORT_2P) 14964220a7eSMarcel Moolenaar *r = PUC_TYPE_PARALLEL; 15064220a7eSMarcel Moolenaar else 15164220a7eSMarcel Moolenaar *r = PUC_TYPE_SERIAL; 15264220a7eSMarcel Moolenaar return (0); 15364220a7eSMarcel Moolenaar case 2: 15464220a7eSMarcel Moolenaar if (cfg->ports == PUC_PORT_1S2P || 15564220a7eSMarcel Moolenaar cfg->ports == PUC_PORT_2S1P) 15664220a7eSMarcel Moolenaar *r = PUC_TYPE_PARALLEL; 15764220a7eSMarcel Moolenaar else 15864220a7eSMarcel Moolenaar *r = PUC_TYPE_SERIAL; 15964220a7eSMarcel Moolenaar return (0); 16064220a7eSMarcel Moolenaar case 4: 16164220a7eSMarcel Moolenaar if (cfg->ports == PUC_PORT_4S1P) 16264220a7eSMarcel Moolenaar *r = PUC_TYPE_PARALLEL; 16364220a7eSMarcel Moolenaar else 16464220a7eSMarcel Moolenaar *r = PUC_TYPE_SERIAL; 16564220a7eSMarcel Moolenaar return (0); 16664220a7eSMarcel Moolenaar } 16764220a7eSMarcel Moolenaar *r = PUC_TYPE_SERIAL; 16864220a7eSMarcel Moolenaar return (0); 16964220a7eSMarcel Moolenaar case PUC_CFG_SETUP: 17064220a7eSMarcel Moolenaar *r = ENXIO; 17164220a7eSMarcel Moolenaar return (0); 17264220a7eSMarcel Moolenaar } 17364220a7eSMarcel Moolenaar 17464220a7eSMarcel Moolenaar return (ENXIO); 17564220a7eSMarcel Moolenaar } 176