ppb_base.c revision 38061
128257Smsmith/*- 238061Smsmith * Copyright (c) 1997, 1998 Nicolas Souchu 328257Smsmith * All rights reserved. 428257Smsmith * 528257Smsmith * Redistribution and use in source and binary forms, with or without 628257Smsmith * modification, are permitted provided that the following conditions 728257Smsmith * are met: 828257Smsmith * 1. Redistributions of source code must retain the above copyright 928257Smsmith * notice, this list of conditions and the following disclaimer. 1028257Smsmith * 2. Redistributions in binary form must reproduce the above copyright 1128257Smsmith * notice, this list of conditions and the following disclaimer in the 1228257Smsmith * documentation and/or other materials provided with the distribution. 1328257Smsmith * 1428257Smsmith * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1528257Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1628257Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1728257Smsmith * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1828257Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1928257Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2028257Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2128257Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2228257Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2328257Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2428257Smsmith * SUCH DAMAGE. 2528257Smsmith * 2638061Smsmith * $Id: ppb_base.c,v 1.3 1997/09/01 00:51:45 bde Exp $ 2728257Smsmith * 2828257Smsmith */ 2928257Smsmith#include <sys/param.h> 3028257Smsmith#include <sys/systm.h> 3128257Smsmith#include <sys/kernel.h> 3228257Smsmith 3328257Smsmith#include <dev/ppbus/ppbconf.h> 3428257Smsmith 3528257Smsmith/* 3628257Smsmith * ppb_intr() 3728257Smsmith * 3828257Smsmith * Function called by ppcintr() when an intr occurs. 3928257Smsmith */ 4028257Smsmithvoid 4128257Smsmithppb_intr(struct ppb_link *pl) 4228257Smsmith{ 4328257Smsmith struct ppb_data *ppb = pl->ppbus; 4428257Smsmith 4528257Smsmith /* 4628257Smsmith * Call chipset dependent code. 4728257Smsmith * Should be filled at chipset initialisation if needed. 4828257Smsmith */ 4928257Smsmith if (pl->adapter->intr_handler) 5028257Smsmith (*pl->adapter->intr_handler)(pl->adapter_unit); 5128257Smsmith 5228257Smsmith /* 5328257Smsmith * Call upper handler iff the bus is owned by a device and 5428257Smsmith * this device has specified an interrupt handler. 5528257Smsmith */ 5628257Smsmith if (ppb->ppb_owner && ppb->ppb_owner->intr) 5728257Smsmith (*ppb->ppb_owner->intr)(ppb->ppb_owner->id_unit); 5828257Smsmith 5928257Smsmith return; 6028257Smsmith} 6128257Smsmith 6228257Smsmith/* 6328257Smsmith * ppb_poll_device() 6428257Smsmith * 6528257Smsmith * Polls the device 6628257Smsmith * 6728257Smsmith * max is a delay in 10-milliseconds 6828257Smsmith */ 6928257Smsmithint 7028257Smsmithppb_poll_device(struct ppb_device *dev, int max, 7128257Smsmith char mask, char status, int how) 7228257Smsmith{ 7328257Smsmith int i, error; 7428257Smsmith 7528257Smsmith for (i = 0; i < max; i++) { 7628257Smsmith if ((ppb_rstr(dev) & mask) == status) 7728257Smsmith return (0); 7828257Smsmith 7928257Smsmith switch (how) { 8028257Smsmith case PPB_NOINTR: 8128257Smsmith /* wait 10 ms */ 8228257Smsmith if ((error = tsleep((caddr_t)dev, PPBPRI, 8328257Smsmith "ppbpoll", hz/100))) 8428257Smsmith return (error); 8528257Smsmith break; 8628257Smsmith 8728257Smsmith case PPB_INTR: 8828257Smsmith default: 8928257Smsmith /* wait 10 ms */ 9028257Smsmith if ((error = tsleep((caddr_t)dev, PPBPRI | PCATCH, 9128257Smsmith "ppbpoll", hz/100))) 9228257Smsmith return (error); 9328257Smsmith break; 9428257Smsmith } 9528257Smsmith } 9628257Smsmith 9728257Smsmith return (EWOULDBLOCK); 9828257Smsmith} 9928257Smsmith 10028257Smsmith/* 10138061Smsmith * ppb_set_mode() 10238061Smsmith * 10338061Smsmith * Set the operating mode of the chipset 10438061Smsmith */ 10538061Smsmithint 10638061Smsmithppb_set_mode(struct ppb_device *dev, int mode) 10738061Smsmith{ 10838061Smsmith struct ppb_data *ppb = dev->ppb; 10938061Smsmith int old_mode = ppb_get_mode(dev); 11038061Smsmith 11138061Smsmith if ((*ppb->ppb_link->adapter->setmode)(dev->id_unit, mode)) 11238061Smsmith return (-1); 11338061Smsmith 11438061Smsmith /* XXX yet device mode = ppbus mode = chipset mode */ 11538061Smsmith dev->mode = ppb->mode = mode; 11638061Smsmith 11738061Smsmith return (old_mode); 11838061Smsmith} 11938061Smsmith 12038061Smsmith/* 12128257Smsmith * ppb_reset_epp_timeout() 12228257Smsmith * 12338061Smsmith * Reset the EPP timeout bit in the status register 12428257Smsmith */ 12528257Smsmithint 12628257Smsmithppb_reset_epp_timeout(struct ppb_device *dev) 12728257Smsmith{ 12828257Smsmith struct ppb_data *ppb = dev->ppb; 12928257Smsmith 13028257Smsmith if (ppb->ppb_owner != dev) 13128257Smsmith return (EACCES); 13228257Smsmith 13328257Smsmith (*ppb->ppb_link->adapter->reset_epp_timeout)(dev->id_unit); 13428257Smsmith 13528257Smsmith return (0); 13628257Smsmith} 13728257Smsmith 13828257Smsmith/* 13928257Smsmith * ppb_ecp_sync() 14028257Smsmith * 14138061Smsmith * Wait for the ECP FIFO to be empty 14228257Smsmith */ 14328257Smsmithint 14428257Smsmithppb_ecp_sync(struct ppb_device *dev) 14528257Smsmith{ 14628257Smsmith struct ppb_data *ppb = dev->ppb; 14728257Smsmith 14828257Smsmith if (ppb->ppb_owner != dev) 14928257Smsmith return (EACCES); 15028257Smsmith 15128257Smsmith (*ppb->ppb_link->adapter->ecp_sync)(dev->id_unit); 15228257Smsmith 15328257Smsmith return (0); 15428257Smsmith} 15528257Smsmith 15628257Smsmith/* 15728257Smsmith * ppb_get_status() 15828257Smsmith * 15938061Smsmith * Read the status register and update the status info 16028257Smsmith */ 16128257Smsmithint 16228257Smsmithppb_get_status(struct ppb_device *dev, struct ppb_status *status) 16328257Smsmith{ 16428257Smsmith struct ppb_data *ppb = dev->ppb; 16528257Smsmith register char r; 16628257Smsmith 16728257Smsmith if (ppb->ppb_owner != dev) 16828257Smsmith return (EACCES); 16928257Smsmith 17028257Smsmith r = status->status = ppb_rstr(dev); 17128257Smsmith 17228257Smsmith status->timeout = r & TIMEOUT; 17328257Smsmith status->error = !(r & nFAULT); 17428257Smsmith status->select = r & SELECT; 17528257Smsmith status->paper_end = r & ERROR; 17628257Smsmith status->ack = !(r & nACK); 17728257Smsmith status->busy = !(r & nBUSY); 17828257Smsmith 17928257Smsmith return (0); 18028257Smsmith} 181