1139749Simp/*- 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 */ 3661541Stanimura 37119418Sobrien#include <sys/cdefs.h> 38119418Sobrien__FBSDID("$FreeBSD: releng/10.3/sys/dev/rp/rp_isa.c 153084 2005-12-04 10:06:06Z ru $"); 39119418Sobrien 4061541Stanimura#include <sys/param.h> 4161541Stanimura#include <sys/systm.h> 4261541Stanimura#include <sys/fcntl.h> 4361541Stanimura#include <sys/malloc.h> 4461541Stanimura#include <sys/tty.h> 4561541Stanimura#include <sys/conf.h> 4661541Stanimura#include <sys/kernel.h> 47129879Sphk#include <sys/module.h> 4861541Stanimura#include <machine/resource.h> 4961541Stanimura#include <machine/bus.h> 5061541Stanimura#include <sys/bus.h> 5161541Stanimura#include <sys/rman.h> 5261541Stanimura 5361541Stanimura#define ROCKET_C 5461541Stanimura#include <dev/rp/rpreg.h> 5561541Stanimura#include <dev/rp/rpvar.h> 5661541Stanimura 5761541Stanimura#include <isa/isavar.h> 5861541Stanimura 5961541Stanimura/* ISA-specific part of CONTROLLER_t */ 6061541Stanimurastruct ISACONTROLLER_T { 6161541Stanimura int MBaseIO; /* rid of the Mudbac controller for this controller */ 6261541Stanimura int MReg0IO; /* offset0 of the Mudbac controller for this controller */ 6361541Stanimura int MReg1IO; /* offset1 of the Mudbac controller for this controller */ 6461541Stanimura int MReg2IO; /* offset2 of the Mudbac controller for this controller */ 6561541Stanimura int MReg3IO; /* offset3 of the Mudbac controller for this controller */ 6661541Stanimura Byte_t MReg2; 6761541Stanimura Byte_t MReg3; 6861541Stanimura}; 6961541Stanimuratypedef struct ISACONTROLLER_T ISACONTROLLER_t; 7061541Stanimura 7161541Stanimura#define ISACTL(ctlp) ((ISACONTROLLER_t *)((ctlp)->bus_ctlp)) 7261541Stanimura 7361541Stanimura/*************************************************************************** 7461541StanimuraFunction: sControllerEOI 7561541StanimuraPurpose: Strobe the MUDBAC's End Of Interrupt bit. 7661541StanimuraCall: sControllerEOI(MudbacCtlP,CtlP) 7761541Stanimura CONTROLLER_T *MudbacCtlP; Ptr to Mudbac controller structure 7861541Stanimura CONTROLLER_T *CtlP; Ptr to controller structure 7961541Stanimura*/ 8061541Stanimura#define sControllerEOI(MudbacCtlP,CtlP) \ 8161541Stanimura rp_writeio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO,ISACTL(CtlP)->MReg2IO,ISACTL(CtlP)->MReg2 | INT_STROB) 8261541Stanimura 8361541Stanimura/*************************************************************************** 8461541StanimuraFunction: sDisAiop 8561541StanimuraPurpose: Disable I/O access to an AIOP 8661541StanimuraCall: sDisAiop(MudbacCtlP,CtlP) 8761541Stanimura CONTROLLER_T *MudbacCtlP; Ptr to Mudbac controller structure 8861541Stanimura CONTROLLER_T *CtlP; Ptr to controller structure 8961541Stanimura int AiopNum; Number of AIOP on controller 9061541Stanimura*/ 9161541Stanimura#define sDisAiop(MudbacCtlP,CtlP,AIOPNUM) \ 9261541Stanimura{ \ 9361541Stanimura ISACTL(CtlP)->MReg3 &= rp_sBitMapClrTbl[AIOPNUM]; \ 9461541Stanimura rp_writeio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO,ISACTL(CtlP)->MReg3IO,ISACTL(CtlP)->MReg3); \ 9561541Stanimura} 9661541Stanimura 9761541Stanimura/*************************************************************************** 9861541StanimuraFunction: sEnAiop 9961541StanimuraPurpose: Enable I/O access to an AIOP 10061541StanimuraCall: sEnAiop(MudbacCtlP,CtlP) 10161541Stanimura CONTROLLER_T *MudbacCtlP; Ptr to Mudbac controller structure 10261541Stanimura CONTROLLER_T *CtlP; Ptr to controller structure 10361541Stanimura int AiopNum; Number of AIOP on controller 10461541Stanimura*/ 10561541Stanimura#define sEnAiop(MudbacCtlP,CtlP,AIOPNUM) \ 10661541Stanimura{ \ 10761541Stanimura ISACTL(CtlP)->MReg3 |= rp_sBitMapSetTbl[AIOPNUM]; \ 10861541Stanimura rp_writeio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO,ISACTL(CtlP)->MReg3IO,ISACTL(CtlP)->MReg3); \ 10961541Stanimura} 11061541Stanimura 11161541Stanimura/*************************************************************************** 11261541StanimuraFunction: sGetControllerIntStatus 11361541StanimuraPurpose: Get the controller interrupt status 11461541StanimuraCall: sGetControllerIntStatus(MudbacCtlP,CtlP) 11561541Stanimura CONTROLLER_T *MudbacCtlP; Ptr to Mudbac controller structure 11661541Stanimura CONTROLLER_T *CtlP; Ptr to controller structure 11761541StanimuraReturn: Byte_t: The controller interrupt status in the lower 4 11861541Stanimura bits. Bits 0 through 3 represent AIOP's 0 11961541Stanimura through 3 respectively. If a bit is set that 12061541Stanimura AIOP is interrupting. Bits 4 through 7 will 12161541Stanimura always be cleared. 12261541Stanimura*/ 12361541Stanimura#define sGetControllerIntStatus(MudbacCtlP,CtlP) \ 12461541Stanimura (rp_readio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO,ISACTL(CtlP)->MReg1IO) & 0x0f) 12561541Stanimura 12661541Stanimurastatic devclass_t rp_devclass; 12761541Stanimurastatic CONTROLLER_t *rp_controller; 12861541Stanimurastatic int rp_nisadevs; 12961541Stanimura 13061541Stanimurastatic int rp_probe(device_t dev); 13161541Stanimurastatic int rp_attach(device_t dev); 13261541Stanimurastatic void rp_isareleaseresource(CONTROLLER_t *ctlp); 13361541Stanimurastatic int sInitController(CONTROLLER_T *CtlP, 13461541Stanimura CONTROLLER_T *MudbacCtlP, 13561541Stanimura int AiopNum, 13661541Stanimura int IRQNum, 13761541Stanimura Byte_t Frequency, 13861541Stanimura int PeriodicOnly); 13961541Stanimurastatic rp_aiop2rid_t rp_isa_aiop2rid; 14061541Stanimurastatic rp_aiop2off_t rp_isa_aiop2off; 14161541Stanimurastatic rp_ctlmask_t rp_isa_ctlmask; 14261541Stanimura 14361541Stanimurastatic int 14461541Stanimurarp_probe(device_t dev) 14561541Stanimura{ 14661541Stanimura int unit; 14761541Stanimura CONTROLLER_t *controller; 14861541Stanimura int num_aiops; 14961541Stanimura CONTROLLER_t *ctlp; 15061541Stanimura int retval; 15161541Stanimura 15261541Stanimura /* 15361541Stanimura * We have no PnP RocketPort cards. 15461541Stanimura * (At least according to LINT) 15561541Stanimura */ 15661541Stanimura if (isa_get_logicalid(dev) != 0) 15761541Stanimura return (ENXIO); 15861541Stanimura 15961541Stanimura /* We need IO port resource to configure an ISA device. */ 16061541Stanimura if (bus_get_resource_count(dev, SYS_RES_IOPORT, 0) == 0) 16161541Stanimura return (ENXIO); 16261541Stanimura 16361541Stanimura unit = device_get_unit(dev); 16461541Stanimura if (unit >= 4) { 16561541Stanimura device_printf(dev, "rpprobe: unit number %d invalid.\n", unit); 16661541Stanimura return (ENXIO); 16761541Stanimura } 16861541Stanimura device_printf(dev, "probing for RocketPort(ISA) unit %d.\n", unit); 16961541Stanimura 17061541Stanimura ctlp = device_get_softc(dev); 17161541Stanimura bzero(ctlp, sizeof(*ctlp)); 17261541Stanimura ctlp->dev = dev; 17361541Stanimura ctlp->aiop2rid = rp_isa_aiop2rid; 17461541Stanimura ctlp->aiop2off = rp_isa_aiop2off; 17561541Stanimura ctlp->ctlmask = rp_isa_ctlmask; 17661541Stanimura 17761541Stanimura /* The IO ports of AIOPs for an ISA controller are discrete. */ 17861541Stanimura ctlp->io_num = 1; 17969781Sdwmalone ctlp->io_rid = malloc(sizeof(*(ctlp->io_rid)) * MAX_AIOPS_PER_BOARD, M_DEVBUF, M_NOWAIT | M_ZERO); 18069781Sdwmalone ctlp->io = malloc(sizeof(*(ctlp->io)) * MAX_AIOPS_PER_BOARD, M_DEVBUF, M_NOWAIT | M_ZERO); 18161541Stanimura if (ctlp->io_rid == NULL || ctlp->io == NULL) { 18261541Stanimura device_printf(dev, "rp_attach: Out of memory.\n"); 18361541Stanimura retval = ENOMEM; 18461541Stanimura goto nogo; 18561541Stanimura } 18661541Stanimura 18769781Sdwmalone ctlp->bus_ctlp = malloc(sizeof(ISACONTROLLER_t) * 1, M_DEVBUF, M_NOWAIT | M_ZERO); 18861541Stanimura if (ctlp->bus_ctlp == NULL) { 18961541Stanimura device_printf(dev, "rp_attach: Out of memory.\n"); 19061541Stanimura retval = ENOMEM; 19161541Stanimura goto nogo; 19261541Stanimura } 19361541Stanimura 19461541Stanimura ctlp->io_rid[0] = 0; 19561541Stanimura if (rp_controller != NULL) { 19661541Stanimura controller = rp_controller; 19761541Stanimura ctlp->io[0] = bus_alloc_resource(dev, SYS_RES_IOPORT, &ctlp->io_rid[0], 0, ~0, 0x40, RF_ACTIVE); 19861541Stanimura } else { 19961541Stanimura controller = rp_controller = ctlp; 20061541Stanimura ctlp->io[0] = bus_alloc_resource(dev, SYS_RES_IOPORT, &ctlp->io_rid[0], 0, ~0, 0x44, RF_ACTIVE); 20161541Stanimura } 20261541Stanimura if (ctlp->io[0] == NULL) { 20361541Stanimura device_printf(dev, "rp_attach: Resource not available.\n"); 20461541Stanimura retval = ENXIO; 20561541Stanimura goto nogo; 20661541Stanimura } 20761541Stanimura 20861541Stanimura num_aiops = sInitController(ctlp, 20961541Stanimura controller, 21061541Stanimura MAX_AIOPS_PER_BOARD, 0, 21161541Stanimura FREQ_DIS, 0); 21261541Stanimura if (num_aiops <= 0) { 21361541Stanimura device_printf(dev, "board%d init failed.\n", unit); 21461541Stanimura retval = ENXIO; 21561541Stanimura goto nogo; 21661541Stanimura } 21761541Stanimura 21861541Stanimura if (rp_controller == NULL) 21961541Stanimura rp_controller = controller; 22061541Stanimura rp_nisadevs++; 22161541Stanimura 22261541Stanimura device_set_desc(dev, "RocketPort ISA"); 22361541Stanimura 22461541Stanimura return (0); 22561541Stanimura 22661541Stanimuranogo: 22761541Stanimura rp_isareleaseresource(ctlp); 22861541Stanimura 22961541Stanimura return (retval); 23061541Stanimura} 23161541Stanimura 23261541Stanimurastatic int 23361541Stanimurarp_attach(device_t dev) 23461541Stanimura{ 23561541Stanimura int unit; 23661541Stanimura int num_ports, num_aiops; 23761541Stanimura int aiop; 23861541Stanimura CONTROLLER_t *ctlp; 23961541Stanimura int retval; 24061541Stanimura 24161541Stanimura unit = device_get_unit(dev); 24261541Stanimura 24361541Stanimura ctlp = device_get_softc(dev); 24461541Stanimura 245153084Sru#ifdef notdef 24661541Stanimura num_aiops = sInitController(ctlp, 24761541Stanimura rp_controller, 24861541Stanimura MAX_AIOPS_PER_BOARD, 0, 24961541Stanimura FREQ_DIS, 0); 25061541Stanimura#else 25161541Stanimura num_aiops = ctlp->NumAiop; 25261541Stanimura#endif /* notdef */ 25361541Stanimura 25461541Stanimura num_ports = 0; 25561541Stanimura for(aiop=0; aiop < num_aiops; aiop++) { 25661541Stanimura sResetAiopByNum(ctlp, aiop); 25761541Stanimura sEnAiop(rp_controller, ctlp, aiop); 25861541Stanimura num_ports += sGetAiopNumChan(ctlp, aiop); 25961541Stanimura } 26061541Stanimura 26161541Stanimura retval = rp_attachcommon(ctlp, num_aiops, num_ports); 26261541Stanimura if (retval != 0) 26361541Stanimura goto nogo; 26461541Stanimura 26561541Stanimura return (0); 26661541Stanimura 26761541Stanimuranogo: 26861541Stanimura rp_isareleaseresource(ctlp); 26961541Stanimura 27061541Stanimura return (retval); 27161541Stanimura} 27261541Stanimura 27361541Stanimurastatic void 27461541Stanimurarp_isareleaseresource(CONTROLLER_t *ctlp) 27561541Stanimura{ 27661541Stanimura int i; 27761541Stanimura 27861541Stanimura rp_releaseresource(ctlp); 27961541Stanimura 28061541Stanimura if (ctlp == rp_controller) 28161541Stanimura rp_controller = NULL; 28261541Stanimura if (ctlp->io != NULL) { 28361541Stanimura for (i = 0 ; i < MAX_AIOPS_PER_BOARD ; i++) 28461541Stanimura if (ctlp->io[i] != NULL) 28561541Stanimura bus_release_resource(ctlp->dev, SYS_RES_IOPORT, ctlp->io_rid[i], ctlp->io[i]); 28661541Stanimura free(ctlp->io, M_DEVBUF); 28761541Stanimura } 28861541Stanimura if (ctlp->io_rid != NULL) 28961541Stanimura free(ctlp->io_rid, M_DEVBUF); 29061541Stanimura if (rp_controller != NULL && rp_controller->io[ISACTL(ctlp)->MBaseIO] != NULL) { 29161541Stanimura bus_release_resource(rp_controller->dev, SYS_RES_IOPORT, rp_controller->io_rid[ISACTL(ctlp)->MBaseIO], rp_controller->io[ISACTL(ctlp)->MBaseIO]); 29261541Stanimura rp_controller->io[ISACTL(ctlp)->MBaseIO] = NULL; 29361541Stanimura rp_controller->io_rid[ISACTL(ctlp)->MBaseIO] = 0; 29461541Stanimura } 29561541Stanimura if (ctlp->bus_ctlp != NULL) 29661541Stanimura free(ctlp->bus_ctlp, M_DEVBUF); 29761541Stanimura} 29861541Stanimura 29961541Stanimura/*************************************************************************** 30061541StanimuraFunction: sInitController 30161541StanimuraPurpose: Initialization of controller global registers and controller 30261541Stanimura structure. 30361541StanimuraCall: sInitController(CtlP,MudbacCtlP,AiopNum, 30461541Stanimura IRQNum,Frequency,PeriodicOnly) 30561541Stanimura CONTROLLER_T *CtlP; Ptr to controller structure 30661541Stanimura CONTROLLER_T *MudbacCtlP; Ptr to Mudbac controller structure 30761541Stanimura int AiopNum; Number of Aiops 30861541Stanimura int IRQNum; Interrupt Request number. Can be any of the following: 30961541Stanimura 0: Disable global interrupts 31061541Stanimura 3: IRQ 3 31161541Stanimura 4: IRQ 4 31261541Stanimura 5: IRQ 5 31361541Stanimura 9: IRQ 9 31461541Stanimura 10: IRQ 10 31561541Stanimura 11: IRQ 11 31661541Stanimura 12: IRQ 12 31761541Stanimura 15: IRQ 15 31861541Stanimura Byte_t Frequency: A flag identifying the frequency 31961541Stanimura of the periodic interrupt, can be any one of the following: 32061541Stanimura FREQ_DIS - periodic interrupt disabled 32161541Stanimura FREQ_137HZ - 137 Hertz 32261541Stanimura FREQ_69HZ - 69 Hertz 32361541Stanimura FREQ_34HZ - 34 Hertz 32461541Stanimura FREQ_17HZ - 17 Hertz 32561541Stanimura FREQ_9HZ - 9 Hertz 32661541Stanimura FREQ_4HZ - 4 Hertz 32761541Stanimura If IRQNum is set to 0 the Frequency parameter is 32861541Stanimura overidden, it is forced to a value of FREQ_DIS. 32961541Stanimura int PeriodicOnly: TRUE if all interrupts except the periodic 33061541Stanimura interrupt are to be blocked. 33161541Stanimura FALSE is both the periodic interrupt and 33261541Stanimura other channel interrupts are allowed. 33361541Stanimura If IRQNum is set to 0 the PeriodicOnly parameter is 33461541Stanimura overidden, it is forced to a value of FALSE. 33561541StanimuraReturn: int: Number of AIOPs on the controller, or CTLID_NULL if controller 33661541Stanimura initialization failed. 33761541Stanimura 33861541StanimuraComments: 33961541Stanimura If periodic interrupts are to be disabled but AIOP interrupts 34061541Stanimura are allowed, set Frequency to FREQ_DIS and PeriodicOnly to FALSE. 34161541Stanimura 34261541Stanimura If interrupts are to be completely disabled set IRQNum to 0. 34361541Stanimura 34461541Stanimura Setting Frequency to FREQ_DIS and PeriodicOnly to TRUE is an 34561541Stanimura invalid combination. 34661541Stanimura 34761541Stanimura This function performs initialization of global interrupt modes, 34861541Stanimura but it does not actually enable global interrupts. To enable 34961541Stanimura and disable global interrupts use functions sEnGlobalInt() and 35061541Stanimura sDisGlobalInt(). Enabling of global interrupts is normally not 35161541Stanimura done until all other initializations are complete. 35261541Stanimura 35361541Stanimura Even if interrupts are globally enabled, they must also be 35461541Stanimura individually enabled for each channel that is to generate 35561541Stanimura interrupts. 35661541Stanimura 35761541StanimuraWarnings: No range checking on any of the parameters is done. 35861541Stanimura 35961541Stanimura No context switches are allowed while executing this function. 36061541Stanimura 36161541Stanimura After this function all AIOPs on the controller are disabled, 36261541Stanimura they can be enabled with sEnAiop(). 36361541Stanimura*/ 36461541Stanimurastatic int 36561541StanimurasInitController( CONTROLLER_T *CtlP, 36661541Stanimura CONTROLLER_T *MudbacCtlP, 36761541Stanimura int AiopNum, 36861541Stanimura int IRQNum, 36961541Stanimura Byte_t Frequency, 37061541Stanimura int PeriodicOnly) 37161541Stanimura{ 37261541Stanimura int i; 37361541Stanimura int ctl_base, aiop_base, aiop_size; 37461541Stanimura 37561541Stanimura CtlP->CtlID = CTLID_0001; /* controller release 1 */ 37661541Stanimura 37761541Stanimura ISACTL(CtlP)->MBaseIO = rp_nisadevs; 37861541Stanimura if (MudbacCtlP->io[ISACTL(CtlP)->MBaseIO] != NULL) { 37961541Stanimura ISACTL(CtlP)->MReg0IO = 0x40 + 0; 38061541Stanimura ISACTL(CtlP)->MReg1IO = 0x40 + 1; 38161541Stanimura ISACTL(CtlP)->MReg2IO = 0x40 + 2; 38261541Stanimura ISACTL(CtlP)->MReg3IO = 0x40 + 3; 38361541Stanimura } else { 38461541Stanimura MudbacCtlP->io_rid[ISACTL(CtlP)->MBaseIO] = ISACTL(CtlP)->MBaseIO; 38561541Stanimura ctl_base = rman_get_start(MudbacCtlP->io[0]) + 0x40 + 0x400 * rp_nisadevs; 38661541Stanimura 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); 38761541Stanimura ISACTL(CtlP)->MReg0IO = 0; 38861541Stanimura ISACTL(CtlP)->MReg1IO = 1; 38961541Stanimura ISACTL(CtlP)->MReg2IO = 2; 39061541Stanimura ISACTL(CtlP)->MReg3IO = 3; 39161541Stanimura } 39261541Stanimura#if 1 39361541Stanimura ISACTL(CtlP)->MReg2 = 0; /* interrupt disable */ 39461541Stanimura ISACTL(CtlP)->MReg3 = 0; /* no periodic interrupts */ 39561541Stanimura#else 39661541Stanimura if(sIRQMap[IRQNum] == 0) /* interrupts globally disabled */ 39761541Stanimura { 39861541Stanimura ISACTL(CtlP)->MReg2 = 0; /* interrupt disable */ 39961541Stanimura ISACTL(CtlP)->MReg3 = 0; /* no periodic interrupts */ 40061541Stanimura } 40161541Stanimura else 40261541Stanimura { 40361541Stanimura ISACTL(CtlP)->MReg2 = sIRQMap[IRQNum]; /* set IRQ number */ 40461541Stanimura ISACTL(CtlP)->MReg3 = Frequency; /* set frequency */ 40561541Stanimura if(PeriodicOnly) /* periodic interrupt only */ 40661541Stanimura { 40761541Stanimura ISACTL(CtlP)->MReg3 |= PERIODIC_ONLY; 40861541Stanimura } 40961541Stanimura } 41061541Stanimura#endif 41161541Stanimura rp_writeio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO,ISACTL(CtlP)->MReg2IO,ISACTL(CtlP)->MReg2); 41261541Stanimura rp_writeio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO,ISACTL(CtlP)->MReg3IO,ISACTL(CtlP)->MReg3); 41361541Stanimura sControllerEOI(MudbacCtlP,CtlP); /* clear EOI if warm init */ 41461541Stanimura 41561541Stanimura /* Init AIOPs */ 41661541Stanimura CtlP->NumAiop = 0; 41761541Stanimura for(i=0; i < AiopNum; i++) 41861541Stanimura { 41961541Stanimura if (CtlP->io[i] == NULL) { 42061541Stanimura CtlP->io_rid[i] = i; 42161541Stanimura aiop_base = rman_get_start(CtlP->io[0]) + 0x400 * i; 42261541Stanimura if (rp_nisadevs == 0) 42361541Stanimura aiop_size = 0x44; 42461541Stanimura else 42561541Stanimura aiop_size = 0x40; 42661541Stanimura 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); 42761541Stanimura } else 42861541Stanimura aiop_base = rman_get_start(CtlP->io[i]); 42961541Stanimura rp_writeio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO, 43061541Stanimura ISACTL(CtlP)->MReg2IO, 43161541Stanimura ISACTL(CtlP)->MReg2 | (i & 0x03)); /* AIOP index */ 43261541Stanimura rp_writeio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO, 43361541Stanimura ISACTL(CtlP)->MReg0IO, 43461541Stanimura (Byte_t)(aiop_base >> 6)); /* set up AIOP I/O in MUDBAC */ 43561541Stanimura sEnAiop(MudbacCtlP,CtlP,i); /* enable the AIOP */ 43661541Stanimura 43761541Stanimura CtlP->AiopID[i] = sReadAiopID(CtlP, i); /* read AIOP ID */ 43861541Stanimura if(CtlP->AiopID[i] == AIOPID_NULL) /* if AIOP does not exist */ 43961541Stanimura { 44061541Stanimura sDisAiop(MudbacCtlP,CtlP,i); /* disable AIOP */ 44161541Stanimura bus_release_resource(CtlP->dev, SYS_RES_IOPORT, CtlP->io_rid[i], CtlP->io[i]); 44261541Stanimura CtlP->io[i] = NULL; 44361541Stanimura break; /* done looking for AIOPs */ 44461541Stanimura } 44561541Stanimura 44661541Stanimura CtlP->AiopNumChan[i] = sReadAiopNumChan(CtlP, i); /* num channels in AIOP */ 44761541Stanimura rp_writeaiop2(CtlP,i,_INDX_ADDR,_CLK_PRE); /* clock prescaler */ 44861541Stanimura rp_writeaiop1(CtlP,i,_INDX_DATA,CLOCK_PRESC); 44961541Stanimura CtlP->NumAiop++; /* bump count of AIOPs */ 45061541Stanimura sDisAiop(MudbacCtlP,CtlP,i); /* disable AIOP */ 45161541Stanimura } 45261541Stanimura 45361541Stanimura if(CtlP->NumAiop == 0) 45461541Stanimura return(-1); 45561541Stanimura else 45661541Stanimura return(CtlP->NumAiop); 45761541Stanimura} 45861541Stanimura 45961541Stanimura/* 46061541Stanimura * ARGSUSED 46161541Stanimura * Maps (aiop, offset) to rid. 46261541Stanimura */ 46361541Stanimurastatic int 46461541Stanimurarp_isa_aiop2rid(int aiop, int offset) 46561541Stanimura{ 46661541Stanimura /* rid equals to aiop for an ISA controller. */ 46761541Stanimura return aiop; 46861541Stanimura} 46961541Stanimura 47061541Stanimura/* 47161541Stanimura * ARGSUSED 47261541Stanimura * Maps (aiop, offset) to the offset of resource. 47361541Stanimura */ 47461541Stanimurastatic int 47561541Stanimurarp_isa_aiop2off(int aiop, int offset) 47661541Stanimura{ 47761541Stanimura /* Each aiop has its own resource. */ 47861541Stanimura return offset; 47961541Stanimura} 48061541Stanimura 48161541Stanimura/* Read the int status for an ISA controller. */ 482105215Sphkstatic unsigned char 48361541Stanimurarp_isa_ctlmask(CONTROLLER_t *ctlp) 48461541Stanimura{ 48561541Stanimura return sGetControllerIntStatus(rp_controller,ctlp); 48661541Stanimura} 48761541Stanimura 48861541Stanimurastatic device_method_t rp_methods[] = { 48961541Stanimura /* Device interface */ 49061541Stanimura DEVMETHOD(device_probe, rp_probe), 49161541Stanimura DEVMETHOD(device_attach, rp_attach), 49261541Stanimura 49361541Stanimura { 0, 0 } 49461541Stanimura}; 49561541Stanimura 49661541Stanimurastatic driver_t rp_driver = { 49761541Stanimura "rp", 49861541Stanimura rp_methods, 49961541Stanimura sizeof(CONTROLLER_t), 50061541Stanimura}; 50161541Stanimura 50261541Stanimura/* 50361541Stanimura * rp can be attached to an isa bus. 50461541Stanimura */ 50561541StanimuraDRIVER_MODULE(rp, isa, rp_driver, rp_devclass, 0, 0); 506