1 /*- 2 * Copyright (c) 1997, 1998, 1999 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 27 #include <sys/cdefs.h> 28 __FBSDID("$FreeBSD$"); 29 30 #include <sys/param.h> 31 #include <sys/systm.h> 32 #include <sys/kernel.h> 33 #include <sys/module.h> 34 #include <sys/bus.h> 35 36 #include <dev/ppbus/ppbconf.h> 37 38 #include "ppbus_if.h" 39 40 #include <dev/ppbus/ppbio.h> 41 42 MODULE_VERSION(ppbus, 1); 43 44 #define DEVTOSOFTC(dev) ((struct ppb_data *)device_get_softc(dev)) 45 46 /* 47 * ppb_poll_bus() 48 * 49 * Polls the bus 50 * 51 * max is a delay in 10-milliseconds 52 */ 53 int 54 ppb_poll_bus(device_t bus, int max, 55 char mask, char status, int how) 56 { 57 int i, j, error; 58 char r; 59 60 /* try at least up to 10ms */ 61 for (j = 0; j < ((how & PPB_POLL) ? max : 1); j++) { 62 for (i = 0; i < 10000; i++) { 63 r = ppb_rstr(bus); 64 DELAY(1); 65 if ((r & mask) == status) 66 return (0); 67 } 68 } 69 70 if (!(how & PPB_POLL)) { 71 for (i = 0; max == PPB_FOREVER || i < max-1; i++) { 72 if ((ppb_rstr(bus) & mask) == status) 73 return (0); 74 75 switch (how) { 76 case PPB_NOINTR: 77 /* wait 10 ms */ 78 tsleep((caddr_t)bus, PPBPRI, "ppbpoll", hz/100); 79 break; 80 81 case PPB_INTR: 82 default: 83 /* wait 10 ms */ 84 if (((error = tsleep((caddr_t)bus, PPBPRI | PCATCH, 85 "ppbpoll", hz/100)) != EWOULDBLOCK) != 0) { 86 return (error); 87 } 88 break; 89 } 90 } 91 } 92 93 return (EWOULDBLOCK); 94 } 95 96 /* 97 * ppb_get_epp_protocol() 98 * 99 * Return the chipset EPP protocol 100 */ 101 int 102 ppb_get_epp_protocol(device_t bus) 103 { 104 uintptr_t protocol; 105 106 BUS_READ_IVAR(device_get_parent(bus), bus, PPC_IVAR_EPP_PROTO, &protocol); 107 108 return (protocol); 109 } 110 111 /* 112 * ppb_get_mode() 113 * 114 */ 115 int 116 ppb_get_mode(device_t bus) 117 { 118 struct ppb_data *ppb = DEVTOSOFTC(bus); 119 120 /* XXX yet device mode = ppbus mode = chipset mode */ 121 return (ppb->mode); 122 } 123 124 /* 125 * ppb_set_mode() 126 * 127 * Set the operating mode of the chipset, return the previous mode 128 */ 129 int 130 ppb_set_mode(device_t bus, int mode) 131 { 132 struct ppb_data *ppb = DEVTOSOFTC(bus); 133 int old_mode = ppb_get_mode(bus); 134 135 if (PPBUS_SETMODE(device_get_parent(bus), mode)) 136 return -1; 137 138 /* XXX yet device mode = ppbus mode = chipset mode */ 139 ppb->mode = (mode & PPB_MASK); 140 141 return (old_mode); 142 } 143 144 /* 145 * ppb_write() 146 * 147 * Write charaters to the port 148 */ 149 int 150 ppb_write(device_t bus, char *buf, int len, int how) 151 { 152 return (PPBUS_WRITE(device_get_parent(bus), buf, len, how)); 153 } 154 155 /* 156 * ppb_reset_epp_timeout() 157 * 158 * Reset the EPP timeout bit in the status register 159 */ 160 int 161 ppb_reset_epp_timeout(device_t bus) 162 { 163 return(PPBUS_RESET_EPP(device_get_parent(bus))); 164 } 165 166 /* 167 * ppb_ecp_sync() 168 * 169 * Wait for the ECP FIFO to be empty 170 */ 171 int 172 ppb_ecp_sync(device_t bus) 173 { 174 return (PPBUS_ECP_SYNC(device_get_parent(bus))); 175 } 176 177 /* 178 * ppb_get_status() 179 * 180 * Read the status register and update the status info 181 */ 182 int 183 ppb_get_status(device_t bus, struct ppb_status *status) 184 { 185 register char r; 186 187 r = status->status = ppb_rstr(bus); 188 189 status->timeout = r & TIMEOUT; 190 status->error = !(r & nFAULT); 191 status->select = r & SELECT; 192 status->paper_end = r & PERROR; 193 status->ack = !(r & nACK); 194 status->busy = !(r & nBUSY); 195 196 return (0); 197 } 198