rp_isa.c revision 69781
161541Stanimura/* 261541Stanimura * Copyright (c) Comtrol Corporation <support@comtrol.com> 361541Stanimura * All rights reserved. 461541Stanimura * 561541Stanimura * ISA-specific part separated from: 661541Stanimura * sys/i386/isa/rp.c,v 1.33 1999/09/28 11:45:27 phk Exp 761541Stanimura * 861541Stanimura * Redistribution and use in source and binary forms, with or without 961541Stanimura * modification, are permitted prodived that the follwoing conditions 1061541Stanimura * are met. 1161541Stanimura * 1. Redistributions of source code must retain the above copyright 1261541Stanimura * notive, this list of conditions and the following disclainer. 1361541Stanimura * 2. Redistributions in binary form must reproduce the above copyright 1461541Stanimura * notice, this list of conditions and the following disclaimer in the 1561541Stanimura * documentation and/or other materials prodided with the distribution. 1661541Stanimura * 3. All advertising materials mentioning features or use of this software 1761541Stanimura * must display the following acknowledgement: 1861541Stanimura * This product includes software developed by Comtrol Corporation. 1961541Stanimura * 4. The name of Comtrol Corporation may not be used to endorse or 2061541Stanimura * promote products derived from this software without specific 2161541Stanimura * prior written permission. 2261541Stanimura * 2361541Stanimura * THIS SOFTWARE IS PROVIDED BY COMTROL CORPORATION ``AS IS'' AND ANY 2461541Stanimura * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2561541Stanimura * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2661541Stanimura * ARE DISCLAIMED. IN NO EVENT SHALL COMTROL CORPORATION BE LIABLE FOR 2761541Stanimura * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2861541Stanimura * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2961541Stanimura * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) 3061541Stanimura * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3161541Stanimura * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3261541Stanimura * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3361541Stanimura * SUCH DAMAGE. 3461541Stanimura * 3561541Stanimura * $FreeBSD: head/sys/dev/rp/rp_isa.c 69781 2000-12-08 21:51:06Z dwmalone $ 3661541Stanimura */ 3761541Stanimura 3861541Stanimura#include <sys/param.h> 3961541Stanimura#include <sys/systm.h> 4061541Stanimura#include <sys/fcntl.h> 4161541Stanimura#include <sys/malloc.h> 4261541Stanimura#include <sys/tty.h> 4361541Stanimura#include <sys/conf.h> 4461541Stanimura#include <sys/kernel.h> 4561541Stanimura#include <machine/resource.h> 4661541Stanimura#include <machine/bus.h> 4761541Stanimura#include <sys/bus.h> 4861541Stanimura#include <sys/rman.h> 4961541Stanimura 5061541Stanimura#define ROCKET_C 5161541Stanimura#include <dev/rp/rpreg.h> 5261541Stanimura#include <dev/rp/rpvar.h> 5361541Stanimura 5461541Stanimura#include <isa/isavar.h> 5561541Stanimura 5661541Stanimura/* ISA-specific part of CONTROLLER_t */ 5761541Stanimurastruct ISACONTROLLER_T { 5861541Stanimura int MBaseIO; /* rid of the Mudbac controller for this controller */ 5961541Stanimura int MReg0IO; /* offset0 of the Mudbac controller for this controller */ 6061541Stanimura int MReg1IO; /* offset1 of the Mudbac controller for this controller */ 6161541Stanimura int MReg2IO; /* offset2 of the Mudbac controller for this controller */ 6261541Stanimura int MReg3IO; /* offset3 of the Mudbac controller for this controller */ 6361541Stanimura Byte_t MReg2; 6461541Stanimura Byte_t MReg3; 6561541Stanimura}; 6661541Stanimuratypedef struct ISACONTROLLER_T ISACONTROLLER_t; 6761541Stanimura 6861541Stanimura#define ISACTL(ctlp) ((ISACONTROLLER_t *)((ctlp)->bus_ctlp)) 6961541Stanimura 7061541Stanimura/*************************************************************************** 7161541StanimuraFunction: sControllerEOI 7261541StanimuraPurpose: Strobe the MUDBAC's End Of Interrupt bit. 7361541StanimuraCall: sControllerEOI(MudbacCtlP,CtlP) 7461541Stanimura CONTROLLER_T *MudbacCtlP; Ptr to Mudbac controller structure 7561541Stanimura CONTROLLER_T *CtlP; Ptr to controller structure 7661541Stanimura*/ 7761541Stanimura#define sControllerEOI(MudbacCtlP,CtlP) \ 7861541Stanimura rp_writeio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO,ISACTL(CtlP)->MReg2IO,ISACTL(CtlP)->MReg2 | INT_STROB) 7961541Stanimura 8061541Stanimura/*************************************************************************** 8161541StanimuraFunction: sDisAiop 8261541StanimuraPurpose: Disable I/O access to an AIOP 8361541StanimuraCall: sDisAiop(MudbacCtlP,CtlP) 8461541Stanimura CONTROLLER_T *MudbacCtlP; Ptr to Mudbac controller structure 8561541Stanimura CONTROLLER_T *CtlP; Ptr to controller structure 8661541Stanimura int AiopNum; Number of AIOP on controller 8761541Stanimura*/ 8861541Stanimura#define sDisAiop(MudbacCtlP,CtlP,AIOPNUM) \ 8961541Stanimura{ \ 9061541Stanimura ISACTL(CtlP)->MReg3 &= rp_sBitMapClrTbl[AIOPNUM]; \ 9161541Stanimura rp_writeio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO,ISACTL(CtlP)->MReg3IO,ISACTL(CtlP)->MReg3); \ 9261541Stanimura} 9361541Stanimura 9461541Stanimura/*************************************************************************** 9561541StanimuraFunction: sEnAiop 9661541StanimuraPurpose: Enable I/O access to an AIOP 9761541StanimuraCall: sEnAiop(MudbacCtlP,CtlP) 9861541Stanimura CONTROLLER_T *MudbacCtlP; Ptr to Mudbac controller structure 9961541Stanimura CONTROLLER_T *CtlP; Ptr to controller structure 10061541Stanimura int AiopNum; Number of AIOP on controller 10161541Stanimura*/ 10261541Stanimura#define sEnAiop(MudbacCtlP,CtlP,AIOPNUM) \ 10361541Stanimura{ \ 10461541Stanimura ISACTL(CtlP)->MReg3 |= rp_sBitMapSetTbl[AIOPNUM]; \ 10561541Stanimura rp_writeio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO,ISACTL(CtlP)->MReg3IO,ISACTL(CtlP)->MReg3); \ 10661541Stanimura} 10761541Stanimura 10861541Stanimura/*************************************************************************** 10961541StanimuraFunction: sGetControllerIntStatus 11061541StanimuraPurpose: Get the controller interrupt status 11161541StanimuraCall: sGetControllerIntStatus(MudbacCtlP,CtlP) 11261541Stanimura CONTROLLER_T *MudbacCtlP; Ptr to Mudbac controller structure 11361541Stanimura CONTROLLER_T *CtlP; Ptr to controller structure 11461541StanimuraReturn: Byte_t: The controller interrupt status in the lower 4 11561541Stanimura bits. Bits 0 through 3 represent AIOP's 0 11661541Stanimura through 3 respectively. If a bit is set that 11761541Stanimura AIOP is interrupting. Bits 4 through 7 will 11861541Stanimura always be cleared. 11961541Stanimura*/ 12061541Stanimura#define sGetControllerIntStatus(MudbacCtlP,CtlP) \ 12161541Stanimura (rp_readio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO,ISACTL(CtlP)->MReg1IO) & 0x0f) 12261541Stanimura 12361541Stanimurastatic devclass_t rp_devclass; 12461541Stanimurastatic CONTROLLER_t *rp_controller; 12561541Stanimurastatic int rp_nisadevs; 12661541Stanimura 12761541Stanimurastatic int rp_probe(device_t dev); 12861541Stanimurastatic int rp_attach(device_t dev); 12961541Stanimurastatic void rp_isareleaseresource(CONTROLLER_t *ctlp); 13061541Stanimurastatic int sInitController(CONTROLLER_T *CtlP, 13161541Stanimura CONTROLLER_T *MudbacCtlP, 13261541Stanimura int AiopNum, 13361541Stanimura int IRQNum, 13461541Stanimura Byte_t Frequency, 13561541Stanimura int PeriodicOnly); 13661541Stanimurastatic rp_aiop2rid_t rp_isa_aiop2rid; 13761541Stanimurastatic rp_aiop2off_t rp_isa_aiop2off; 13861541Stanimurastatic rp_ctlmask_t rp_isa_ctlmask; 13961541Stanimura 14061541Stanimurastatic int 14161541Stanimurarp_probe(device_t dev) 14261541Stanimura{ 14361541Stanimura int unit; 14461541Stanimura CONTROLLER_t *controller; 14561541Stanimura int num_aiops; 14661541Stanimura CONTROLLER_t *ctlp; 14761541Stanimura int retval; 14861541Stanimura 14961541Stanimura /* 15061541Stanimura * We have no PnP RocketPort cards. 15161541Stanimura * (At least according to LINT) 15261541Stanimura */ 15361541Stanimura if (isa_get_logicalid(dev) != 0) 15461541Stanimura return (ENXIO); 15561541Stanimura 15661541Stanimura /* We need IO port resource to configure an ISA device. */ 15761541Stanimura if (bus_get_resource_count(dev, SYS_RES_IOPORT, 0) == 0) 15861541Stanimura return (ENXIO); 15961541Stanimura 16061541Stanimura unit = device_get_unit(dev); 16161541Stanimura if (unit >= 4) { 16261541Stanimura device_printf(dev, "rpprobe: unit number %d invalid.\n", unit); 16361541Stanimura return (ENXIO); 16461541Stanimura } 16561541Stanimura device_printf(dev, "probing for RocketPort(ISA) unit %d.\n", unit); 16661541Stanimura 16761541Stanimura ctlp = device_get_softc(dev); 16861541Stanimura bzero(ctlp, sizeof(*ctlp)); 16961541Stanimura ctlp->dev = dev; 17061541Stanimura ctlp->aiop2rid = rp_isa_aiop2rid; 17161541Stanimura ctlp->aiop2off = rp_isa_aiop2off; 17261541Stanimura ctlp->ctlmask = rp_isa_ctlmask; 17361541Stanimura 17461541Stanimura /* The IO ports of AIOPs for an ISA controller are discrete. */ 17561541Stanimura ctlp->io_num = 1; 17669781Sdwmalone ctlp->io_rid = malloc(sizeof(*(ctlp->io_rid)) * MAX_AIOPS_PER_BOARD, M_DEVBUF, M_NOWAIT | M_ZERO); 17769781Sdwmalone ctlp->io = malloc(sizeof(*(ctlp->io)) * MAX_AIOPS_PER_BOARD, M_DEVBUF, M_NOWAIT | M_ZERO); 17861541Stanimura if (ctlp->io_rid == NULL || ctlp->io == NULL) { 17961541Stanimura device_printf(dev, "rp_attach: Out of memory.\n"); 18061541Stanimura retval = ENOMEM; 18161541Stanimura goto nogo; 18261541Stanimura } 18361541Stanimura 18469781Sdwmalone ctlp->bus_ctlp = malloc(sizeof(ISACONTROLLER_t) * 1, M_DEVBUF, M_NOWAIT | M_ZERO); 18561541Stanimura if (ctlp->bus_ctlp == NULL) { 18661541Stanimura device_printf(dev, "rp_attach: Out of memory.\n"); 18761541Stanimura retval = ENOMEM; 18861541Stanimura goto nogo; 18961541Stanimura } 19061541Stanimura 19161541Stanimura ctlp->io_rid[0] = 0; 19261541Stanimura if (rp_controller != NULL) { 19361541Stanimura controller = rp_controller; 19461541Stanimura ctlp->io[0] = bus_alloc_resource(dev, SYS_RES_IOPORT, &ctlp->io_rid[0], 0, ~0, 0x40, RF_ACTIVE); 19561541Stanimura } else { 19661541Stanimura controller = rp_controller = ctlp; 19761541Stanimura ctlp->io[0] = bus_alloc_resource(dev, SYS_RES_IOPORT, &ctlp->io_rid[0], 0, ~0, 0x44, RF_ACTIVE); 19861541Stanimura } 19961541Stanimura if (ctlp->io[0] == NULL) { 20061541Stanimura device_printf(dev, "rp_attach: Resource not available.\n"); 20161541Stanimura retval = ENXIO; 20261541Stanimura goto nogo; 20361541Stanimura } 20461541Stanimura 20561541Stanimura num_aiops = sInitController(ctlp, 20661541Stanimura controller, 20761541Stanimura MAX_AIOPS_PER_BOARD, 0, 20861541Stanimura FREQ_DIS, 0); 20961541Stanimura if (num_aiops <= 0) { 21061541Stanimura device_printf(dev, "board%d init failed.\n", unit); 21161541Stanimura retval = ENXIO; 21261541Stanimura goto nogo; 21361541Stanimura } 21461541Stanimura 21561541Stanimura if (rp_controller == NULL) 21661541Stanimura rp_controller = controller; 21761541Stanimura rp_nisadevs++; 21861541Stanimura 21961541Stanimura device_set_desc(dev, "RocketPort ISA"); 22061541Stanimura 22161541Stanimura return (0); 22261541Stanimura 22361541Stanimuranogo: 22461541Stanimura rp_isareleaseresource(ctlp); 22561541Stanimura 22661541Stanimura return (retval); 22761541Stanimura} 22861541Stanimura 22961541Stanimurastatic int 23061541Stanimurarp_attach(device_t dev) 23161541Stanimura{ 23261541Stanimura int unit; 23361541Stanimura int num_ports, num_aiops; 23461541Stanimura int aiop; 23561541Stanimura CONTROLLER_t *ctlp; 23661541Stanimura int retval; 23761541Stanimura 23861541Stanimura unit = device_get_unit(dev); 23961541Stanimura 24061541Stanimura ctlp = device_get_softc(dev); 24161541Stanimura 24261541Stanimura#if notdef 24361541Stanimura num_aiops = sInitController(ctlp, 24461541Stanimura rp_controller, 24561541Stanimura MAX_AIOPS_PER_BOARD, 0, 24661541Stanimura FREQ_DIS, 0); 24761541Stanimura#else 24861541Stanimura num_aiops = ctlp->NumAiop; 24961541Stanimura#endif /* notdef */ 25061541Stanimura 25161541Stanimura num_ports = 0; 25261541Stanimura for(aiop=0; aiop < num_aiops; aiop++) { 25361541Stanimura sResetAiopByNum(ctlp, aiop); 25461541Stanimura sEnAiop(rp_controller, ctlp, aiop); 25561541Stanimura num_ports += sGetAiopNumChan(ctlp, aiop); 25661541Stanimura } 25761541Stanimura 25861541Stanimura retval = rp_attachcommon(ctlp, num_aiops, num_ports); 25961541Stanimura if (retval != 0) 26061541Stanimura goto nogo; 26161541Stanimura 26261541Stanimura return (0); 26361541Stanimura 26461541Stanimuranogo: 26561541Stanimura rp_isareleaseresource(ctlp); 26661541Stanimura 26761541Stanimura return (retval); 26861541Stanimura} 26961541Stanimura 27061541Stanimurastatic void 27161541Stanimurarp_isareleaseresource(CONTROLLER_t *ctlp) 27261541Stanimura{ 27361541Stanimura int i; 27461541Stanimura 27561541Stanimura rp_releaseresource(ctlp); 27661541Stanimura 27761541Stanimura if (ctlp == rp_controller) 27861541Stanimura rp_controller = NULL; 27961541Stanimura if (ctlp->io != NULL) { 28061541Stanimura for (i = 0 ; i < MAX_AIOPS_PER_BOARD ; i++) 28161541Stanimura if (ctlp->io[i] != NULL) 28261541Stanimura bus_release_resource(ctlp->dev, SYS_RES_IOPORT, ctlp->io_rid[i], ctlp->io[i]); 28361541Stanimura free(ctlp->io, M_DEVBUF); 28461541Stanimura } 28561541Stanimura if (ctlp->io_rid != NULL) 28661541Stanimura free(ctlp->io_rid, M_DEVBUF); 28761541Stanimura if (rp_controller != NULL && rp_controller->io[ISACTL(ctlp)->MBaseIO] != NULL) { 28861541Stanimura bus_release_resource(rp_controller->dev, SYS_RES_IOPORT, rp_controller->io_rid[ISACTL(ctlp)->MBaseIO], rp_controller->io[ISACTL(ctlp)->MBaseIO]); 28961541Stanimura rp_controller->io[ISACTL(ctlp)->MBaseIO] = NULL; 29061541Stanimura rp_controller->io_rid[ISACTL(ctlp)->MBaseIO] = 0; 29161541Stanimura } 29261541Stanimura if (ctlp->bus_ctlp != NULL) 29361541Stanimura free(ctlp->bus_ctlp, M_DEVBUF); 29461541Stanimura} 29561541Stanimura 29661541Stanimura/*************************************************************************** 29761541StanimuraFunction: sInitController 29861541StanimuraPurpose: Initialization of controller global registers and controller 29961541Stanimura structure. 30061541StanimuraCall: sInitController(CtlP,MudbacCtlP,AiopNum, 30161541Stanimura IRQNum,Frequency,PeriodicOnly) 30261541Stanimura CONTROLLER_T *CtlP; Ptr to controller structure 30361541Stanimura CONTROLLER_T *MudbacCtlP; Ptr to Mudbac controller structure 30461541Stanimura int AiopNum; Number of Aiops 30561541Stanimura int IRQNum; Interrupt Request number. Can be any of the following: 30661541Stanimura 0: Disable global interrupts 30761541Stanimura 3: IRQ 3 30861541Stanimura 4: IRQ 4 30961541Stanimura 5: IRQ 5 31061541Stanimura 9: IRQ 9 31161541Stanimura 10: IRQ 10 31261541Stanimura 11: IRQ 11 31361541Stanimura 12: IRQ 12 31461541Stanimura 15: IRQ 15 31561541Stanimura Byte_t Frequency: A flag identifying the frequency 31661541Stanimura of the periodic interrupt, can be any one of the following: 31761541Stanimura FREQ_DIS - periodic interrupt disabled 31861541Stanimura FREQ_137HZ - 137 Hertz 31961541Stanimura FREQ_69HZ - 69 Hertz 32061541Stanimura FREQ_34HZ - 34 Hertz 32161541Stanimura FREQ_17HZ - 17 Hertz 32261541Stanimura FREQ_9HZ - 9 Hertz 32361541Stanimura FREQ_4HZ - 4 Hertz 32461541Stanimura If IRQNum is set to 0 the Frequency parameter is 32561541Stanimura overidden, it is forced to a value of FREQ_DIS. 32661541Stanimura int PeriodicOnly: TRUE if all interrupts except the periodic 32761541Stanimura interrupt are to be blocked. 32861541Stanimura FALSE is both the periodic interrupt and 32961541Stanimura other channel interrupts are allowed. 33061541Stanimura If IRQNum is set to 0 the PeriodicOnly parameter is 33161541Stanimura overidden, it is forced to a value of FALSE. 33261541StanimuraReturn: int: Number of AIOPs on the controller, or CTLID_NULL if controller 33361541Stanimura initialization failed. 33461541Stanimura 33561541StanimuraComments: 33661541Stanimura If periodic interrupts are to be disabled but AIOP interrupts 33761541Stanimura are allowed, set Frequency to FREQ_DIS and PeriodicOnly to FALSE. 33861541Stanimura 33961541Stanimura If interrupts are to be completely disabled set IRQNum to 0. 34061541Stanimura 34161541Stanimura Setting Frequency to FREQ_DIS and PeriodicOnly to TRUE is an 34261541Stanimura invalid combination. 34361541Stanimura 34461541Stanimura This function performs initialization of global interrupt modes, 34561541Stanimura but it does not actually enable global interrupts. To enable 34661541Stanimura and disable global interrupts use functions sEnGlobalInt() and 34761541Stanimura sDisGlobalInt(). Enabling of global interrupts is normally not 34861541Stanimura done until all other initializations are complete. 34961541Stanimura 35061541Stanimura Even if interrupts are globally enabled, they must also be 35161541Stanimura individually enabled for each channel that is to generate 35261541Stanimura interrupts. 35361541Stanimura 35461541StanimuraWarnings: No range checking on any of the parameters is done. 35561541Stanimura 35661541Stanimura No context switches are allowed while executing this function. 35761541Stanimura 35861541Stanimura After this function all AIOPs on the controller are disabled, 35961541Stanimura they can be enabled with sEnAiop(). 36061541Stanimura*/ 36161541Stanimurastatic int 36261541StanimurasInitController( CONTROLLER_T *CtlP, 36361541Stanimura CONTROLLER_T *MudbacCtlP, 36461541Stanimura int AiopNum, 36561541Stanimura int IRQNum, 36661541Stanimura Byte_t Frequency, 36761541Stanimura int PeriodicOnly) 36861541Stanimura{ 36961541Stanimura int i; 37061541Stanimura int ctl_base, aiop_base, aiop_size; 37161541Stanimura 37261541Stanimura CtlP->CtlID = CTLID_0001; /* controller release 1 */ 37361541Stanimura 37461541Stanimura ISACTL(CtlP)->MBaseIO = rp_nisadevs; 37561541Stanimura if (MudbacCtlP->io[ISACTL(CtlP)->MBaseIO] != NULL) { 37661541Stanimura ISACTL(CtlP)->MReg0IO = 0x40 + 0; 37761541Stanimura ISACTL(CtlP)->MReg1IO = 0x40 + 1; 37861541Stanimura ISACTL(CtlP)->MReg2IO = 0x40 + 2; 37961541Stanimura ISACTL(CtlP)->MReg3IO = 0x40 + 3; 38061541Stanimura } else { 38161541Stanimura MudbacCtlP->io_rid[ISACTL(CtlP)->MBaseIO] = ISACTL(CtlP)->MBaseIO; 38261541Stanimura ctl_base = rman_get_start(MudbacCtlP->io[0]) + 0x40 + 0x400 * rp_nisadevs; 38361541Stanimura MudbacCtlP->io[ISACTL(CtlP)->MBaseIO] = bus_alloc_resource(MudbacCtlP->dev, SYS_RES_IOPORT, &CtlP->io_rid[ISACTL(CtlP)->MBaseIO], ctl_base, ctl_base + 3, 4, RF_ACTIVE); 38461541Stanimura ISACTL(CtlP)->MReg0IO = 0; 38561541Stanimura ISACTL(CtlP)->MReg1IO = 1; 38661541Stanimura ISACTL(CtlP)->MReg2IO = 2; 38761541Stanimura ISACTL(CtlP)->MReg3IO = 3; 38861541Stanimura } 38961541Stanimura#if 1 39061541Stanimura ISACTL(CtlP)->MReg2 = 0; /* interrupt disable */ 39161541Stanimura ISACTL(CtlP)->MReg3 = 0; /* no periodic interrupts */ 39261541Stanimura#else 39361541Stanimura if(sIRQMap[IRQNum] == 0) /* interrupts globally disabled */ 39461541Stanimura { 39561541Stanimura ISACTL(CtlP)->MReg2 = 0; /* interrupt disable */ 39661541Stanimura ISACTL(CtlP)->MReg3 = 0; /* no periodic interrupts */ 39761541Stanimura } 39861541Stanimura else 39961541Stanimura { 40061541Stanimura ISACTL(CtlP)->MReg2 = sIRQMap[IRQNum]; /* set IRQ number */ 40161541Stanimura ISACTL(CtlP)->MReg3 = Frequency; /* set frequency */ 40261541Stanimura if(PeriodicOnly) /* periodic interrupt only */ 40361541Stanimura { 40461541Stanimura ISACTL(CtlP)->MReg3 |= PERIODIC_ONLY; 40561541Stanimura } 40661541Stanimura } 40761541Stanimura#endif 40861541Stanimura rp_writeio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO,ISACTL(CtlP)->MReg2IO,ISACTL(CtlP)->MReg2); 40961541Stanimura rp_writeio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO,ISACTL(CtlP)->MReg3IO,ISACTL(CtlP)->MReg3); 41061541Stanimura sControllerEOI(MudbacCtlP,CtlP); /* clear EOI if warm init */ 41161541Stanimura 41261541Stanimura /* Init AIOPs */ 41361541Stanimura CtlP->NumAiop = 0; 41461541Stanimura for(i=0; i < AiopNum; i++) 41561541Stanimura { 41661541Stanimura if (CtlP->io[i] == NULL) { 41761541Stanimura CtlP->io_rid[i] = i; 41861541Stanimura aiop_base = rman_get_start(CtlP->io[0]) + 0x400 * i; 41961541Stanimura if (rp_nisadevs == 0) 42061541Stanimura aiop_size = 0x44; 42161541Stanimura else 42261541Stanimura aiop_size = 0x40; 42361541Stanimura CtlP->io[i] = bus_alloc_resource(CtlP->dev, SYS_RES_IOPORT, &CtlP->io_rid[i], aiop_base, aiop_base + aiop_size - 1, aiop_size, RF_ACTIVE); 42461541Stanimura } else 42561541Stanimura aiop_base = rman_get_start(CtlP->io[i]); 42661541Stanimura rp_writeio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO, 42761541Stanimura ISACTL(CtlP)->MReg2IO, 42861541Stanimura ISACTL(CtlP)->MReg2 | (i & 0x03)); /* AIOP index */ 42961541Stanimura rp_writeio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO, 43061541Stanimura ISACTL(CtlP)->MReg0IO, 43161541Stanimura (Byte_t)(aiop_base >> 6)); /* set up AIOP I/O in MUDBAC */ 43261541Stanimura sEnAiop(MudbacCtlP,CtlP,i); /* enable the AIOP */ 43361541Stanimura 43461541Stanimura CtlP->AiopID[i] = sReadAiopID(CtlP, i); /* read AIOP ID */ 43561541Stanimura if(CtlP->AiopID[i] == AIOPID_NULL) /* if AIOP does not exist */ 43661541Stanimura { 43761541Stanimura sDisAiop(MudbacCtlP,CtlP,i); /* disable AIOP */ 43861541Stanimura bus_release_resource(CtlP->dev, SYS_RES_IOPORT, CtlP->io_rid[i], CtlP->io[i]); 43961541Stanimura CtlP->io[i] = NULL; 44061541Stanimura break; /* done looking for AIOPs */ 44161541Stanimura } 44261541Stanimura 44361541Stanimura CtlP->AiopNumChan[i] = sReadAiopNumChan(CtlP, i); /* num channels in AIOP */ 44461541Stanimura rp_writeaiop2(CtlP,i,_INDX_ADDR,_CLK_PRE); /* clock prescaler */ 44561541Stanimura rp_writeaiop1(CtlP,i,_INDX_DATA,CLOCK_PRESC); 44661541Stanimura CtlP->NumAiop++; /* bump count of AIOPs */ 44761541Stanimura sDisAiop(MudbacCtlP,CtlP,i); /* disable AIOP */ 44861541Stanimura } 44961541Stanimura 45061541Stanimura if(CtlP->NumAiop == 0) 45161541Stanimura return(-1); 45261541Stanimura else 45361541Stanimura return(CtlP->NumAiop); 45461541Stanimura} 45561541Stanimura 45661541Stanimura/* 45761541Stanimura * ARGSUSED 45861541Stanimura * Maps (aiop, offset) to rid. 45961541Stanimura */ 46061541Stanimurastatic int 46161541Stanimurarp_isa_aiop2rid(int aiop, int offset) 46261541Stanimura{ 46361541Stanimura /* rid equals to aiop for an ISA controller. */ 46461541Stanimura return aiop; 46561541Stanimura} 46661541Stanimura 46761541Stanimura/* 46861541Stanimura * ARGSUSED 46961541Stanimura * Maps (aiop, offset) to the offset of resource. 47061541Stanimura */ 47161541Stanimurastatic int 47261541Stanimurarp_isa_aiop2off(int aiop, int offset) 47361541Stanimura{ 47461541Stanimura /* Each aiop has its own resource. */ 47561541Stanimura return offset; 47661541Stanimura} 47761541Stanimura 47861541Stanimura/* Read the int status for an ISA controller. */ 47961541Stanimuraunsigned char 48061541Stanimurarp_isa_ctlmask(CONTROLLER_t *ctlp) 48161541Stanimura{ 48261541Stanimura return sGetControllerIntStatus(rp_controller,ctlp); 48361541Stanimura} 48461541Stanimura 48561541Stanimurastatic device_method_t rp_methods[] = { 48661541Stanimura /* Device interface */ 48761541Stanimura DEVMETHOD(device_probe, rp_probe), 48861541Stanimura DEVMETHOD(device_attach, rp_attach), 48961541Stanimura 49061541Stanimura { 0, 0 } 49161541Stanimura}; 49261541Stanimura 49361541Stanimurastatic driver_t rp_driver = { 49461541Stanimura "rp", 49561541Stanimura rp_methods, 49661541Stanimura sizeof(CONTROLLER_t), 49761541Stanimura}; 49861541Stanimura 49961541Stanimura/* 50061541Stanimura * rp can be attached to an isa bus. 50161541Stanimura */ 50261541StanimuraDRIVER_MODULE(rp, isa, rp_driver, rp_devclass, 0, 0); 503