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: ppb_base.c,v 1.2 1997/08/28 10:15:12 msmith Exp $ 27 * 28 */ 29 #include <sys/param.h> 30 #include <sys/systm.h> 31 #include <sys/kernel.h> 32 33 #include <dev/ppbus/ppbconf.h> 34 35 /* 36 * ppb_intr() 37 * 38 * Function called by ppcintr() when an intr occurs. 39 */ 40 void 41 ppb_intr(struct ppb_link *pl) 42 { 43 struct ppb_data *ppb = pl->ppbus; 44 45 /* 46 * Call chipset dependent code. 47 * Should be filled at chipset initialisation if needed. 48 */ 49 if (pl->adapter->intr_handler) 50 (*pl->adapter->intr_handler)(pl->adapter_unit); 51 52 /* 53 * Call upper handler iff the bus is owned by a device and 54 * this device has specified an interrupt handler. 55 */ 56 if (ppb->ppb_owner && ppb->ppb_owner->intr) 57 (*ppb->ppb_owner->intr)(ppb->ppb_owner->id_unit); 58 59 return; 60 } 61 62 /* 63 * ppb_poll_device() 64 * 65 * Polls the device 66 * 67 * max is a delay in 10-milliseconds 68 */ 69 int 70 ppb_poll_device(struct ppb_device *dev, int max, 71 char mask, char status, int how) 72 { 73 int i, error; 74 75 for (i = 0; i < max; i++) { 76 if ((ppb_rstr(dev) & mask) == status) 77 return (0); 78 79 switch (how) { 80 case PPB_NOINTR: 81 /* wait 10 ms */ 82 if ((error = tsleep((caddr_t)dev, PPBPRI, 83 "ppbpoll", hz/100))) 84 return (error); 85 break; 86 87 case PPB_INTR: 88 default: 89 /* wait 10 ms */ 90 if ((error = tsleep((caddr_t)dev, PPBPRI | PCATCH, 91 "ppbpoll", hz/100))) 92 return (error); 93 break; 94 } 95 } 96 97 return (EWOULDBLOCK); 98 } 99 100 /* 101 * ppb_reset_epp_timeout() 102 * 103 * Reset the EPP timeout bit in the status register. 104 */ 105 int 106 ppb_reset_epp_timeout(struct ppb_device *dev) 107 { 108 struct ppb_data *ppb = dev->ppb; 109 110 if (ppb->ppb_owner != dev) 111 return (EACCES); 112 113 (*ppb->ppb_link->adapter->reset_epp_timeout)(dev->id_unit); 114 115 return (0); 116 } 117 118 /* 119 * ppb_ecp_sync() 120 * 121 * Wait for the ECP FIFO to be empty. 122 */ 123 int 124 ppb_ecp_sync(struct ppb_device *dev) 125 { 126 struct ppb_data *ppb = dev->ppb; 127 128 if (ppb->ppb_owner != dev) 129 return (EACCES); 130 131 (*ppb->ppb_link->adapter->ecp_sync)(dev->id_unit); 132 133 return (0); 134 } 135 136 /* 137 * ppb_get_mode() 138 * 139 * Read the mode (SPP, EPP...) of the chipset. 140 */ 141 int 142 ppb_get_mode(struct ppb_device *dev) 143 { 144 return (dev->ppb->ppb_link->mode); 145 } 146 147 /* 148 * ppb_get_epp_protocol() 149 * 150 * Read the EPP protocol (1.9 or 1.7). 151 */ 152 int 153 ppb_get_epp_protocol(struct ppb_device *dev) 154 { 155 return (dev->ppb->ppb_link->epp_protocol); 156 } 157 158 /* 159 * ppb_get_irq() 160 * 161 * Return the irq, 0 if none. 162 */ 163 int 164 ppb_get_irq(struct ppb_device *dev) 165 { 166 return (dev->ppb->ppb_link->id_irq); 167 } 168 169 /* 170 * ppb_get_status() 171 * 172 * Read the status register and update the status info. 173 */ 174 int 175 ppb_get_status(struct ppb_device *dev, struct ppb_status *status) 176 { 177 struct ppb_data *ppb = dev->ppb; 178 register char r; 179 180 if (ppb->ppb_owner != dev) 181 return (EACCES); 182 183 r = status->status = ppb_rstr(dev); 184 185 status->timeout = r & TIMEOUT; 186 status->error = !(r & nFAULT); 187 status->select = r & SELECT; 188 status->paper_end = r & ERROR; 189 status->ack = !(r & nACK); 190 status->busy = !(r & nBUSY); 191 192 return (0); 193 } 194