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