ppb_base.c revision 63458
128257Smsmith/*- 255939Snsouch * Copyright (c) 1997, 1998, 1999 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 * 2650477Speter * $FreeBSD: head/sys/dev/ppbus/ppb_base.c 63458 2000-07-18 20:16:16Z n_hibma $ 2728257Smsmith * 2828257Smsmith */ 2928257Smsmith#include <sys/param.h> 3028257Smsmith#include <sys/systm.h> 3128257Smsmith#include <sys/kernel.h> 3255939Snsouch#include <sys/module.h> 3355939Snsouch#include <sys/bus.h> 3455939Snsouch 3542475Snsouch#include <machine/clock.h> 3628257Smsmith 3728257Smsmith#include <dev/ppbus/ppbconf.h> 3855939Snsouch 3955939Snsouch#include "ppbus_if.h" 4028257Smsmith 4155939Snsouch#include <dev/ppbus/ppbio.h> 4255939Snsouch 4355939Snsouch#define DEVTOSOFTC(dev) ((struct ppb_data *)device_get_softc(dev)) 4455939Snsouch 4528257Smsmith/* 4655939Snsouch * ppb_poll_bus() 4728257Smsmith * 4855939Snsouch * Polls the bus 4928257Smsmith * 5028257Smsmith * max is a delay in 10-milliseconds 5128257Smsmith */ 5228257Smsmithint 5355939Snsouchppb_poll_bus(device_t bus, int max, 5455939Snsouch char mask, char status, int how) 5528257Smsmith{ 5642475Snsouch int i, j, error; 5742475Snsouch char r; 5828257Smsmith 5942475Snsouch /* try at least up to 10ms */ 6042475Snsouch for (j = 0; j < ((how & PPB_POLL) ? max : 1); j++) { 6142475Snsouch for (i = 0; i < 10000; i++) { 6255939Snsouch r = ppb_rstr(bus); 6342475Snsouch DELAY(1); 6442475Snsouch if ((r & mask) == status) 6542475Snsouch return (0); 6642475Snsouch } 6742475Snsouch } 6842475Snsouch 6942475Snsouch if (!(how & PPB_POLL)) { 7042475Snsouch for (i = 0; max == PPB_FOREVER || i < max-1; i++) { 7155939Snsouch if ((ppb_rstr(bus) & mask) == status) 7228257Smsmith return (0); 7328257Smsmith 7428257Smsmith switch (how) { 7528257Smsmith case PPB_NOINTR: 7628257Smsmith /* wait 10 ms */ 7755939Snsouch tsleep((caddr_t)bus, PPBPRI, "ppbpoll", hz/100); 7828257Smsmith break; 7928257Smsmith 8028257Smsmith case PPB_INTR: 8128257Smsmith default: 8228257Smsmith /* wait 10 ms */ 8355939Snsouch if (((error = tsleep((caddr_t)bus, PPBPRI | PCATCH, 8443295Sdillon "ppbpoll", hz/100)) != EWOULDBLOCK) != 0) { 8528257Smsmith return (error); 8643295Sdillon } 8728257Smsmith break; 8828257Smsmith } 8942475Snsouch } 9028257Smsmith } 9128257Smsmith 9228257Smsmith return (EWOULDBLOCK); 9328257Smsmith} 9428257Smsmith 9528257Smsmith/* 9655939Snsouch * ppb_get_epp_protocol() 9738061Smsmith * 9855939Snsouch * Return the chipset EPP protocol 9938061Smsmith */ 10038061Smsmithint 10155939Snsouchppb_get_epp_protocol(device_t bus) 10238061Smsmith{ 10355939Snsouch uintptr_t protocol; 10438061Smsmith 10555939Snsouch BUS_READ_IVAR(device_get_parent(bus), bus, PPC_IVAR_EPP_PROTO, &protocol); 10638061Smsmith 10755939Snsouch return (protocol); 10855939Snsouch} 10955939Snsouch 11055939Snsouch/* 11155939Snsouch * ppb_get_mode() 11255939Snsouch * 11355939Snsouch */ 11455939Snsouchint 11555939Snsouchppb_get_mode(device_t bus) 11655939Snsouch{ 11755939Snsouch struct ppb_data *ppb = DEVTOSOFTC(bus); 11855939Snsouch 11938061Smsmith /* XXX yet device mode = ppbus mode = chipset mode */ 12055939Snsouch return (ppb->mode); 12155939Snsouch} 12238061Smsmith 12355939Snsouch/* 12455939Snsouch * ppb_set_mode() 12555939Snsouch * 12655939Snsouch * Set the operating mode of the chipset, return the previous mode 12755939Snsouch */ 12855939Snsouchint 12955939Snsouchppb_set_mode(device_t bus, int mode) 13055939Snsouch{ 13155939Snsouch struct ppb_data *ppb = DEVTOSOFTC(bus); 13255939Snsouch int old_mode = ppb_get_mode(bus); 13355939Snsouch 13463458Sn_hibma if (PPBUS_SETMODE(device_get_parent(bus), mode)) 13563458Sn_hibma return -1; 13655939Snsouch 13763458Sn_hibma /* XXX yet device mode = ppbus mode = chipset mode */ 13863458Sn_hibma ppb->mode = (mode & PPB_MASK); 13963458Sn_hibma 14038061Smsmith return (old_mode); 14138061Smsmith} 14238061Smsmith 14338061Smsmith/* 14442475Snsouch * ppb_write() 14542475Snsouch * 14642475Snsouch * Write charaters to the port 14742475Snsouch */ 14842475Snsouchint 14955939Snsouchppb_write(device_t bus, char *buf, int len, int how) 15042475Snsouch{ 15155939Snsouch return (PPBUS_WRITE(device_get_parent(bus), buf, len, how)); 15242475Snsouch} 15342475Snsouch 15442475Snsouch/* 15528257Smsmith * ppb_reset_epp_timeout() 15628257Smsmith * 15738061Smsmith * Reset the EPP timeout bit in the status register 15828257Smsmith */ 15928257Smsmithint 16055939Snsouchppb_reset_epp_timeout(device_t bus) 16128257Smsmith{ 16255939Snsouch return(PPBUS_RESET_EPP(device_get_parent(bus))); 16328257Smsmith} 16428257Smsmith 16528257Smsmith/* 16628257Smsmith * ppb_ecp_sync() 16728257Smsmith * 16838061Smsmith * Wait for the ECP FIFO to be empty 16928257Smsmith */ 17028257Smsmithint 17155939Snsouchppb_ecp_sync(device_t bus) 17228257Smsmith{ 17355939Snsouch return (PPBUS_ECP_SYNC(device_get_parent(bus))); 17428257Smsmith} 17528257Smsmith 17628257Smsmith/* 17728257Smsmith * ppb_get_status() 17828257Smsmith * 17938061Smsmith * Read the status register and update the status info 18028257Smsmith */ 18128257Smsmithint 18255939Snsouchppb_get_status(device_t bus, struct ppb_status *status) 18328257Smsmith{ 18428257Smsmith register char r; 18528257Smsmith 18655939Snsouch r = status->status = ppb_rstr(bus); 18728257Smsmith 18828257Smsmith status->timeout = r & TIMEOUT; 18928257Smsmith status->error = !(r & nFAULT); 19028257Smsmith status->select = r & SELECT; 19139134Snsouch status->paper_end = r & PERROR; 19228257Smsmith status->ack = !(r & nACK); 19328257Smsmith status->busy = !(r & nBUSY); 19428257Smsmith 19528257Smsmith return (0); 19628257Smsmith} 197