ppb_base.c revision 119418
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 */ 26119418Sobrien 27119418Sobrien#include <sys/cdefs.h> 28119418Sobrien__FBSDID("$FreeBSD: head/sys/dev/ppbus/ppb_base.c 119418 2003-08-24 17:55:58Z obrien $"); 29119418Sobrien 3028257Smsmith#include <sys/param.h> 3128257Smsmith#include <sys/systm.h> 3228257Smsmith#include <sys/kernel.h> 3355939Snsouch#include <sys/module.h> 3455939Snsouch#include <sys/bus.h> 3555939Snsouch 3628257Smsmith#include <dev/ppbus/ppbconf.h> 3755939Snsouch 3855939Snsouch#include "ppbus_if.h" 3928257Smsmith 4055939Snsouch#include <dev/ppbus/ppbio.h> 4155939Snsouch 42119284SimpMODULE_VERSION(ppbus, 1); 43119284Simp 4455939Snsouch#define DEVTOSOFTC(dev) ((struct ppb_data *)device_get_softc(dev)) 4555939Snsouch 4628257Smsmith/* 4755939Snsouch * ppb_poll_bus() 4828257Smsmith * 4955939Snsouch * Polls the bus 5028257Smsmith * 5128257Smsmith * max is a delay in 10-milliseconds 5228257Smsmith */ 5328257Smsmithint 5455939Snsouchppb_poll_bus(device_t bus, int max, 5555939Snsouch char mask, char status, int how) 5628257Smsmith{ 5742475Snsouch int i, j, error; 5842475Snsouch char r; 5928257Smsmith 6042475Snsouch /* try at least up to 10ms */ 6142475Snsouch for (j = 0; j < ((how & PPB_POLL) ? max : 1); j++) { 6242475Snsouch for (i = 0; i < 10000; i++) { 6355939Snsouch r = ppb_rstr(bus); 6442475Snsouch DELAY(1); 6542475Snsouch if ((r & mask) == status) 6642475Snsouch return (0); 6742475Snsouch } 6842475Snsouch } 6942475Snsouch 7042475Snsouch if (!(how & PPB_POLL)) { 7142475Snsouch for (i = 0; max == PPB_FOREVER || i < max-1; i++) { 7255939Snsouch if ((ppb_rstr(bus) & mask) == status) 7328257Smsmith return (0); 7428257Smsmith 7528257Smsmith switch (how) { 7628257Smsmith case PPB_NOINTR: 7728257Smsmith /* wait 10 ms */ 7855939Snsouch tsleep((caddr_t)bus, PPBPRI, "ppbpoll", hz/100); 7928257Smsmith break; 8028257Smsmith 8128257Smsmith case PPB_INTR: 8228257Smsmith default: 8328257Smsmith /* wait 10 ms */ 8455939Snsouch if (((error = tsleep((caddr_t)bus, PPBPRI | PCATCH, 8543295Sdillon "ppbpoll", hz/100)) != EWOULDBLOCK) != 0) { 8628257Smsmith return (error); 8743295Sdillon } 8828257Smsmith break; 8928257Smsmith } 9042475Snsouch } 9128257Smsmith } 9228257Smsmith 9328257Smsmith return (EWOULDBLOCK); 9428257Smsmith} 9528257Smsmith 9628257Smsmith/* 9755939Snsouch * ppb_get_epp_protocol() 9838061Smsmith * 9955939Snsouch * Return the chipset EPP protocol 10038061Smsmith */ 10138061Smsmithint 10255939Snsouchppb_get_epp_protocol(device_t bus) 10338061Smsmith{ 10455939Snsouch uintptr_t protocol; 10538061Smsmith 10655939Snsouch BUS_READ_IVAR(device_get_parent(bus), bus, PPC_IVAR_EPP_PROTO, &protocol); 10738061Smsmith 10855939Snsouch return (protocol); 10955939Snsouch} 11055939Snsouch 11155939Snsouch/* 11255939Snsouch * ppb_get_mode() 11355939Snsouch * 11455939Snsouch */ 11555939Snsouchint 11655939Snsouchppb_get_mode(device_t bus) 11755939Snsouch{ 11855939Snsouch struct ppb_data *ppb = DEVTOSOFTC(bus); 11955939Snsouch 12038061Smsmith /* XXX yet device mode = ppbus mode = chipset mode */ 12155939Snsouch return (ppb->mode); 12255939Snsouch} 12338061Smsmith 12455939Snsouch/* 12555939Snsouch * ppb_set_mode() 12655939Snsouch * 12755939Snsouch * Set the operating mode of the chipset, return the previous mode 12855939Snsouch */ 12955939Snsouchint 13055939Snsouchppb_set_mode(device_t bus, int mode) 13155939Snsouch{ 13255939Snsouch struct ppb_data *ppb = DEVTOSOFTC(bus); 13355939Snsouch int old_mode = ppb_get_mode(bus); 13455939Snsouch 13563458Sn_hibma if (PPBUS_SETMODE(device_get_parent(bus), mode)) 13663458Sn_hibma return -1; 13755939Snsouch 13863458Sn_hibma /* XXX yet device mode = ppbus mode = chipset mode */ 13963458Sn_hibma ppb->mode = (mode & PPB_MASK); 14063458Sn_hibma 14138061Smsmith return (old_mode); 14238061Smsmith} 14338061Smsmith 14438061Smsmith/* 14542475Snsouch * ppb_write() 14642475Snsouch * 14742475Snsouch * Write charaters to the port 14842475Snsouch */ 14942475Snsouchint 15055939Snsouchppb_write(device_t bus, char *buf, int len, int how) 15142475Snsouch{ 15255939Snsouch return (PPBUS_WRITE(device_get_parent(bus), buf, len, how)); 15342475Snsouch} 15442475Snsouch 15542475Snsouch/* 15628257Smsmith * ppb_reset_epp_timeout() 15728257Smsmith * 15838061Smsmith * Reset the EPP timeout bit in the status register 15928257Smsmith */ 16028257Smsmithint 16155939Snsouchppb_reset_epp_timeout(device_t bus) 16228257Smsmith{ 16355939Snsouch return(PPBUS_RESET_EPP(device_get_parent(bus))); 16428257Smsmith} 16528257Smsmith 16628257Smsmith/* 16728257Smsmith * ppb_ecp_sync() 16828257Smsmith * 16938061Smsmith * Wait for the ECP FIFO to be empty 17028257Smsmith */ 17128257Smsmithint 17255939Snsouchppb_ecp_sync(device_t bus) 17328257Smsmith{ 17455939Snsouch return (PPBUS_ECP_SYNC(device_get_parent(bus))); 17528257Smsmith} 17628257Smsmith 17728257Smsmith/* 17828257Smsmith * ppb_get_status() 17928257Smsmith * 18038061Smsmith * Read the status register and update the status info 18128257Smsmith */ 18228257Smsmithint 18355939Snsouchppb_get_status(device_t bus, struct ppb_status *status) 18428257Smsmith{ 18528257Smsmith register char r; 18628257Smsmith 18755939Snsouch r = status->status = ppb_rstr(bus); 18828257Smsmith 18928257Smsmith status->timeout = r & TIMEOUT; 19028257Smsmith status->error = !(r & nFAULT); 19128257Smsmith status->select = r & SELECT; 19239134Snsouch status->paper_end = r & PERROR; 19328257Smsmith status->ack = !(r & nACK); 19428257Smsmith status->busy = !(r & nBUSY); 19528257Smsmith 19628257Smsmith return (0); 19728257Smsmith} 198