puc_cfg.c revision 259065
1251607Sdim/*- 2251607Sdim * Copyright (c) 2006 Marcel Moolenaar 3251607Sdim * All rights reserved. 4251607Sdim * 5251607Sdim * Redistribution and use in source and binary forms, with or without 6251607Sdim * modification, are permitted provided that the following conditions 7251607Sdim * are met: 8251607Sdim * 9251607Sdim * 1. Redistributions of source code must retain the above copyright 10251607Sdim * notice, this list of conditions and the following disclaimer. 11288943Sdim * 2. Redistributions in binary form must reproduce the above copyright 12288943Sdim * notice, this list of conditions and the following disclaimer in the 13251607Sdim * documentation and/or other materials provided with the distribution. 14251607Sdim * 15251607Sdim * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16288943Sdim * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17288943Sdim * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18276479Sdim * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19276479Sdim * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20288943Sdim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21288943Sdim * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22288943Sdim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23288943Sdim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24251607Sdim * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25288943Sdim */ 26288943Sdim 27288943Sdim#include <sys/cdefs.h> 28288943Sdim__FBSDID("$FreeBSD: releng/10.0/sys/dev/puc/puc_cfg.c 160030 2006-06-29 16:27:19Z obrien $"); 29288943Sdim 30288943Sdim#include <sys/param.h> 31288943Sdim#include <sys/systm.h> 32288943Sdim#include <sys/bus.h> 33288943Sdim#include <sys/rman.h> 34288943Sdim 35288943Sdim#include <dev/puc/puc_bus.h> 36288943Sdim#include <dev/puc/puc_cfg.h> 37288943Sdim#include <dev/puc/puc_bfe.h> 38288943Sdim 39288943Sdimint 40288943Sdimpuc_config(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port, intptr_t *r) 41288943Sdim{ 42251607Sdim const struct puc_cfg *cfg = sc->sc_cfg; 43251607Sdim int error; 44276479Sdim 45251607Sdim if (cfg->config_function != NULL) { 46251607Sdim error = cfg->config_function(sc, cmd, port, r); 47251607Sdim if (!error) 48288943Sdim return (0); 49251607Sdim } else 50251607Sdim error = EDOOFUS; 51 52 switch (cmd) { 53 case PUC_CFG_GET_CLOCK: 54 if (cfg->clock < 0) 55 return (error); 56 *r = cfg->clock; 57 return (0); 58 case PUC_CFG_GET_DESC: 59 if (cfg->desc == NULL) 60 return (error); 61 *r = (intptr_t)cfg->desc; 62 return (0); 63 case PUC_CFG_GET_ILR: 64 *r = PUC_ILR_NONE; 65 return (0); 66 case PUC_CFG_GET_LEN: 67 /* The length of bus space needed by the port. */ 68 *r = 8; 69 return (0); 70 case PUC_CFG_GET_NPORTS: 71 /* The number of ports on this card. */ 72 switch (cfg->ports) { 73 case PUC_PORT_NONSTANDARD: 74 return (error); 75 case PUC_PORT_1P: 76 case PUC_PORT_1S: 77 *r = 1; 78 return (0); 79 case PUC_PORT_1S1P: 80 case PUC_PORT_2P: 81 case PUC_PORT_2S: 82 *r = 2; 83 return (0); 84 case PUC_PORT_1S2P: 85 case PUC_PORT_2S1P: 86 case PUC_PORT_3S: 87 *r = 3; 88 return (0); 89 case PUC_PORT_4S: 90 *r = 4; 91 return (0); 92 case PUC_PORT_4S1P: 93 *r = 5; 94 return (0); 95 case PUC_PORT_6S: 96 *r = 6; 97 return (0); 98 case PUC_PORT_8S: 99 *r = 8; 100 return (0); 101 case PUC_PORT_12S: 102 *r = 12; 103 return (0); 104 case PUC_PORT_16S: 105 *r = 16; 106 return (0); 107 } 108 break; 109 case PUC_CFG_GET_OFS: 110 /* The offset relative to the RID. */ 111 if (cfg->d_ofs < 0) 112 return (error); 113 *r = port * cfg->d_ofs; 114 return (0); 115 case PUC_CFG_GET_RID: 116 /* The RID for this port. */ 117 if (port == 0) { 118 if (cfg->rid < 0) 119 return (error); 120 *r = cfg->rid; 121 return (0); 122 } 123 if (cfg->d_rid < 0) 124 return (error); 125 if (cfg->rid < 0) { 126 error = puc_config(sc, PUC_CFG_GET_RID, 0, r); 127 if (error) 128 return (error); 129 } else 130 *r = cfg->rid; 131 *r += port * cfg->d_rid; 132 return (0); 133 case PUC_CFG_GET_TYPE: 134 /* The type of this port. */ 135 if (cfg->ports == PUC_PORT_NONSTANDARD) 136 return (error); 137 switch (port) { 138 case 0: 139 if (cfg->ports == PUC_PORT_1P || 140 cfg->ports == PUC_PORT_2P) 141 *r = PUC_TYPE_PARALLEL; 142 else 143 *r = PUC_TYPE_SERIAL; 144 return (0); 145 case 1: 146 if (cfg->ports == PUC_PORT_1S1P || 147 cfg->ports == PUC_PORT_1S2P || 148 cfg->ports == PUC_PORT_2P) 149 *r = PUC_TYPE_PARALLEL; 150 else 151 *r = PUC_TYPE_SERIAL; 152 return (0); 153 case 2: 154 if (cfg->ports == PUC_PORT_1S2P || 155 cfg->ports == PUC_PORT_2S1P) 156 *r = PUC_TYPE_PARALLEL; 157 else 158 *r = PUC_TYPE_SERIAL; 159 return (0); 160 case 4: 161 if (cfg->ports == PUC_PORT_4S1P) 162 *r = PUC_TYPE_PARALLEL; 163 else 164 *r = PUC_TYPE_SERIAL; 165 return (0); 166 } 167 *r = PUC_TYPE_SERIAL; 168 return (0); 169 case PUC_CFG_SETUP: 170 *r = ENXIO; 171 return (0); 172 } 173 174 return (ENXIO); 175} 176