1158124Smarcel/*- 2158124Smarcel * Copyright (c) 2006 Marcel Moolenaar 3158124Smarcel * All rights reserved. 4158124Smarcel * 5158124Smarcel * Redistribution and use in source and binary forms, with or without 6158124Smarcel * modification, are permitted provided that the following conditions 7158124Smarcel * are met: 8158124Smarcel * 9158124Smarcel * 1. Redistributions of source code must retain the above copyright 10158124Smarcel * notice, this list of conditions and the following disclaimer. 11158124Smarcel * 2. Redistributions in binary form must reproduce the above copyright 12158124Smarcel * notice, this list of conditions and the following disclaimer in the 13158124Smarcel * documentation and/or other materials provided with the distribution. 14158124Smarcel * 15158124Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16158124Smarcel * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17158124Smarcel * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18158124Smarcel * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19158124Smarcel * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20158124Smarcel * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21158124Smarcel * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22158124Smarcel * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23158124Smarcel * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24158124Smarcel * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25158124Smarcel */ 26158124Smarcel 27158124Smarcel#include <sys/cdefs.h> 28158124Smarcel__FBSDID("$FreeBSD$"); 29158124Smarcel 30158124Smarcel#include <sys/param.h> 31158124Smarcel#include <sys/systm.h> 32158124Smarcel#include <sys/bus.h> 33158124Smarcel#include <sys/rman.h> 34263109Srstone#include <sys/sysctl.h> 35158124Smarcel 36158124Smarcel#include <dev/puc/puc_bus.h> 37158124Smarcel#include <dev/puc/puc_cfg.h> 38160030Sobrien#include <dev/puc/puc_bfe.h> 39158124Smarcel 40158124Smarcelint 41158124Smarcelpuc_config(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port, intptr_t *r) 42158124Smarcel{ 43158124Smarcel const struct puc_cfg *cfg = sc->sc_cfg; 44158124Smarcel int error; 45158124Smarcel 46158124Smarcel if (cfg->config_function != NULL) { 47158124Smarcel error = cfg->config_function(sc, cmd, port, r); 48158124Smarcel if (!error) 49158124Smarcel return (0); 50158124Smarcel } else 51158124Smarcel error = EDOOFUS; 52158124Smarcel 53158124Smarcel switch (cmd) { 54158124Smarcel case PUC_CFG_GET_CLOCK: 55158124Smarcel if (cfg->clock < 0) 56158124Smarcel return (error); 57158124Smarcel *r = cfg->clock; 58158124Smarcel return (0); 59158124Smarcel case PUC_CFG_GET_DESC: 60158124Smarcel if (cfg->desc == NULL) 61158124Smarcel return (error); 62158124Smarcel *r = (intptr_t)cfg->desc; 63158124Smarcel return (0); 64158124Smarcel case PUC_CFG_GET_ILR: 65158124Smarcel *r = PUC_ILR_NONE; 66158124Smarcel return (0); 67158124Smarcel case PUC_CFG_GET_LEN: 68158124Smarcel /* The length of bus space needed by the port. */ 69158124Smarcel *r = 8; 70158124Smarcel return (0); 71158124Smarcel case PUC_CFG_GET_NPORTS: 72158124Smarcel /* The number of ports on this card. */ 73158124Smarcel switch (cfg->ports) { 74158124Smarcel case PUC_PORT_NONSTANDARD: 75158124Smarcel return (error); 76158124Smarcel case PUC_PORT_1P: 77158124Smarcel case PUC_PORT_1S: 78158124Smarcel *r = 1; 79158124Smarcel return (0); 80158124Smarcel case PUC_PORT_1S1P: 81158124Smarcel case PUC_PORT_2P: 82158124Smarcel case PUC_PORT_2S: 83158124Smarcel *r = 2; 84158124Smarcel return (0); 85158124Smarcel case PUC_PORT_1S2P: 86158124Smarcel case PUC_PORT_2S1P: 87158124Smarcel case PUC_PORT_3S: 88158124Smarcel *r = 3; 89158124Smarcel return (0); 90158124Smarcel case PUC_PORT_4S: 91158124Smarcel *r = 4; 92158124Smarcel return (0); 93158124Smarcel case PUC_PORT_4S1P: 94158124Smarcel *r = 5; 95158124Smarcel return (0); 96158124Smarcel case PUC_PORT_6S: 97158124Smarcel *r = 6; 98158124Smarcel return (0); 99158124Smarcel case PUC_PORT_8S: 100158124Smarcel *r = 8; 101158124Smarcel return (0); 102158124Smarcel case PUC_PORT_12S: 103158124Smarcel *r = 12; 104158124Smarcel return (0); 105158124Smarcel case PUC_PORT_16S: 106158124Smarcel *r = 16; 107158124Smarcel return (0); 108158124Smarcel } 109158124Smarcel break; 110158124Smarcel case PUC_CFG_GET_OFS: 111158124Smarcel /* The offset relative to the RID. */ 112158124Smarcel if (cfg->d_ofs < 0) 113158124Smarcel return (error); 114158124Smarcel *r = port * cfg->d_ofs; 115158124Smarcel return (0); 116158124Smarcel case PUC_CFG_GET_RID: 117158124Smarcel /* The RID for this port. */ 118158124Smarcel if (port == 0) { 119158124Smarcel if (cfg->rid < 0) 120158124Smarcel return (error); 121158124Smarcel *r = cfg->rid; 122158124Smarcel return (0); 123158124Smarcel } 124158124Smarcel if (cfg->d_rid < 0) 125158124Smarcel return (error); 126158124Smarcel if (cfg->rid < 0) { 127158124Smarcel error = puc_config(sc, PUC_CFG_GET_RID, 0, r); 128158124Smarcel if (error) 129158124Smarcel return (error); 130158124Smarcel } else 131158124Smarcel *r = cfg->rid; 132158124Smarcel *r += port * cfg->d_rid; 133158124Smarcel return (0); 134158124Smarcel case PUC_CFG_GET_TYPE: 135158124Smarcel /* The type of this port. */ 136158124Smarcel if (cfg->ports == PUC_PORT_NONSTANDARD) 137158124Smarcel return (error); 138158124Smarcel switch (port) { 139158124Smarcel case 0: 140158124Smarcel if (cfg->ports == PUC_PORT_1P || 141158124Smarcel cfg->ports == PUC_PORT_2P) 142158124Smarcel *r = PUC_TYPE_PARALLEL; 143158124Smarcel else 144158124Smarcel *r = PUC_TYPE_SERIAL; 145158124Smarcel return (0); 146158124Smarcel case 1: 147158124Smarcel if (cfg->ports == PUC_PORT_1S1P || 148158124Smarcel cfg->ports == PUC_PORT_1S2P || 149158124Smarcel cfg->ports == PUC_PORT_2P) 150158124Smarcel *r = PUC_TYPE_PARALLEL; 151158124Smarcel else 152158124Smarcel *r = PUC_TYPE_SERIAL; 153158124Smarcel return (0); 154158124Smarcel case 2: 155158124Smarcel if (cfg->ports == PUC_PORT_1S2P || 156158124Smarcel cfg->ports == PUC_PORT_2S1P) 157158124Smarcel *r = PUC_TYPE_PARALLEL; 158158124Smarcel else 159158124Smarcel *r = PUC_TYPE_SERIAL; 160158124Smarcel return (0); 161158124Smarcel case 4: 162158124Smarcel if (cfg->ports == PUC_PORT_4S1P) 163158124Smarcel *r = PUC_TYPE_PARALLEL; 164158124Smarcel else 165158124Smarcel *r = PUC_TYPE_SERIAL; 166158124Smarcel return (0); 167158124Smarcel } 168158124Smarcel *r = PUC_TYPE_SERIAL; 169158124Smarcel return (0); 170158124Smarcel case PUC_CFG_SETUP: 171158124Smarcel *r = ENXIO; 172158124Smarcel return (0); 173158124Smarcel } 174158124Smarcel 175158124Smarcel return (ENXIO); 176158124Smarcel} 177