ppb_base.c revision 28257
1/*- 2 * Copyright (c) 1997 Nicolas Souchu 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $Id$ 27 * 28 */ 29#include <sys/param.h> 30#include <sys/systm.h> 31#include <sys/errno.h> 32#include <sys/conf.h> 33#include <sys/proc.h> 34#include <sys/buf.h> 35#include <sys/kernel.h> 36#include <sys/malloc.h> 37#include <sys/uio.h> 38#include <sys/syslog.h> 39 40#include <machine/clock.h> 41#include <machine/lpt.h> 42 43#include <vm/vm.h> 44#include <vm/vm_param.h> 45#include <vm/pmap.h> 46 47#include <i386/isa/isa.h> 48#include <i386/isa/isa_device.h> 49 50#include <dev/ppbus/ppbconf.h> 51 52/* 53 * ppb_intr() 54 * 55 * Function called by ppcintr() when an intr occurs. 56 */ 57void 58ppb_intr(struct ppb_link *pl) 59{ 60 struct ppb_data *ppb = pl->ppbus; 61 62 /* 63 * Call chipset dependent code. 64 * Should be filled at chipset initialisation if needed. 65 */ 66 if (pl->adapter->intr_handler) 67 (*pl->adapter->intr_handler)(pl->adapter_unit); 68 69 /* 70 * Call upper handler iff the bus is owned by a device and 71 * this device has specified an interrupt handler. 72 */ 73 if (ppb->ppb_owner && ppb->ppb_owner->intr) 74 (*ppb->ppb_owner->intr)(ppb->ppb_owner->id_unit); 75 76 return; 77} 78 79/* 80 * ppb_poll_device() 81 * 82 * Polls the device 83 * 84 * max is a delay in 10-milliseconds 85 */ 86int 87ppb_poll_device(struct ppb_device *dev, int max, 88 char mask, char status, int how) 89{ 90 int i, error; 91 92 for (i = 0; i < max; i++) { 93 if ((ppb_rstr(dev) & mask) == status) 94 return (0); 95 96 switch (how) { 97 case PPB_NOINTR: 98 /* wait 10 ms */ 99 if ((error = tsleep((caddr_t)dev, PPBPRI, 100 "ppbpoll", hz/100))) 101 return (error); 102 break; 103 104 case PPB_INTR: 105 default: 106 /* wait 10 ms */ 107 if ((error = tsleep((caddr_t)dev, PPBPRI | PCATCH, 108 "ppbpoll", hz/100))) 109 return (error); 110 break; 111 } 112 } 113 114 return (EWOULDBLOCK); 115} 116 117/* 118 * ppb_reset_epp_timeout() 119 * 120 * Reset the EPP timeout bit in the status register. 121 */ 122int 123ppb_reset_epp_timeout(struct ppb_device *dev) 124{ 125 struct ppb_data *ppb = dev->ppb; 126 127 if (ppb->ppb_owner != dev) 128 return (EACCES); 129 130 (*ppb->ppb_link->adapter->reset_epp_timeout)(dev->id_unit); 131 132 return (0); 133} 134 135/* 136 * ppb_ecp_sync() 137 * 138 * Wait for the ECP FIFO to be empty. 139 */ 140int 141ppb_ecp_sync(struct ppb_device *dev) 142{ 143 struct ppb_data *ppb = dev->ppb; 144 145 if (ppb->ppb_owner != dev) 146 return (EACCES); 147 148 (*ppb->ppb_link->adapter->ecp_sync)(dev->id_unit); 149 150 return (0); 151} 152 153/* 154 * ppb_get_mode() 155 * 156 * Read the mode (SPP, EPP...) of the chipset. 157 */ 158int 159ppb_get_mode(struct ppb_device *dev) 160{ 161 return (dev->ppb->ppb_link->mode); 162} 163 164/* 165 * ppb_get_epp_protocol() 166 * 167 * Read the EPP protocol (1.9 or 1.7). 168 */ 169int 170ppb_get_epp_protocol(struct ppb_device *dev) 171{ 172 return (dev->ppb->ppb_link->epp_protocol); 173} 174 175/* 176 * ppb_get_irq() 177 * 178 * Return the irq, 0 if none. 179 */ 180int 181ppb_get_irq(struct ppb_device *dev) 182{ 183 return (dev->ppb->ppb_link->id_irq); 184} 185 186/* 187 * ppb_get_status() 188 * 189 * Read the status register and update the status info. 190 */ 191int 192ppb_get_status(struct ppb_device *dev, struct ppb_status *status) 193{ 194 struct ppb_data *ppb = dev->ppb; 195 register char r; 196 197 if (ppb->ppb_owner != dev) 198 return (EACCES); 199 200 r = status->status = ppb_rstr(dev); 201 202 status->timeout = r & TIMEOUT; 203 status->error = !(r & nFAULT); 204 status->select = r & SELECT; 205 status->paper_end = r & ERROR; 206 status->ack = !(r & nACK); 207 status->busy = !(r & nBUSY); 208 209 return (0); 210} 211