1119418Sobrien/*- 2120477Sscottl * Copyright (c) 2000-03 ICP vortex GmbH 3120477Sscottl * Copyright (c) 2002-03 Intel Corporation 4120477Sscottl * Copyright (c) 2003 Adaptec Inc. 589580Smsmith * All Rights Reserved 689580Smsmith * 789580Smsmith * Redistribution and use in source and binary forms, with or without 889580Smsmith * modification, are permitted provided that the following conditions 989580Smsmith * are met: 1089580Smsmith * 1. Redistributions of source code must retain the above copyright 1189580Smsmith * notice, this list of conditions, and the following disclaimer, 1289580Smsmith * without modification, immediately at the beginning of the file. 1389580Smsmith * 2. Redistributions in binary form must reproduce the above copyright 1489580Smsmith * notice, this list of conditions and the following disclaimer in the 1589580Smsmith * documentation and/or other materials provided with the distribution. 1689580Smsmith * 3. The name of the author may not be used to endorse or promote products 1789580Smsmith * derived from this software without specific prior written permission. 1889580Smsmith * 1989580Smsmith * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 2089580Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2189580Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2289580Smsmith * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 2389580Smsmith * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2489580Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2589580Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2689580Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2789580Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2889580Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2989580Smsmith * SUCH DAMAGE. 3089580Smsmith */ 3189580Smsmith 32119418Sobrien#include <sys/cdefs.h> 33119418Sobrien__FBSDID("$FreeBSD$"); 34119418Sobrien 3589580Smsmith/* 3689580Smsmith * iir_pci.c: PCI Bus Attachment for Intel Integrated RAID Controller driver 3789580Smsmith * 3889580Smsmith * Written by: Achim Leubner <achim.leubner@intel.com> 39120477Sscottl * Written by: Achim Leubner <achim_leubner@adaptec.com> 4089580Smsmith * Fixes/Additions: Boji Tony Kannanthanam <boji.t.kannanthanam@intel.com> 4189580Smsmith * 4289580Smsmith * TODO: 4389580Smsmith */ 4489580Smsmith 4589580Smsmith/* #include "opt_iir.h" */ 4689580Smsmith 4789580Smsmith#include <sys/param.h> 4889580Smsmith#include <sys/systm.h> 4995533Smike#include <sys/endian.h> 5089580Smsmith#include <sys/kernel.h> 51117126Sscottl#include <sys/lock.h> 52117126Sscottl#include <sys/mutex.h> 5389580Smsmith#include <sys/module.h> 5489580Smsmith#include <sys/bus.h> 5589580Smsmith 5689580Smsmith#include <machine/bus.h> 5789580Smsmith#include <machine/resource.h> 5889580Smsmith#include <sys/rman.h> 5989580Smsmith 60119280Simp#include <dev/pci/pcireg.h> 61119280Simp#include <dev/pci/pcivar.h> 6289580Smsmith 6389580Smsmith#include <cam/scsi/scsi_all.h> 6489580Smsmith 6589580Smsmith#include <dev/iir/iir.h> 6689580Smsmith 6789580Smsmith/* Mapping registers for various areas */ 68119690Sjhb#define PCI_DPMEM PCIR_BAR(0) 6989580Smsmith 7089580Smsmith/* Product numbers for Fibre-Channel are greater than or equal to 0x200 */ 7189580Smsmith#define GDT_PCI_PRODUCT_FC 0x200 7289580Smsmith 7389580Smsmith/* PCI SRAM structure */ 7489580Smsmith#define GDT_MAGIC 0x00 /* u_int32_t, controller ID from BIOS */ 7589580Smsmith#define GDT_NEED_DEINIT 0x04 /* u_int16_t, switch between BIOS/driver */ 7689580Smsmith#define GDT_SWITCH_SUPPORT 0x06 /* u_int8_t, see GDT_NEED_DEINIT */ 7789580Smsmith#define GDT_OS_USED 0x10 /* u_int8_t [16], OS code per service */ 7889580Smsmith#define GDT_FW_MAGIC 0x3c /* u_int8_t, controller ID from firmware */ 7989580Smsmith#define GDT_SRAM_SZ 0x40 8089580Smsmith 8189580Smsmith/* DPRAM PCI controllers */ 8289580Smsmith#define GDT_DPR_IF 0x00 /* interface area */ 8389580Smsmith#define GDT_6SR (0xff0 - GDT_SRAM_SZ) 8489580Smsmith#define GDT_SEMA1 0xff1 /* volatile u_int8_t, command semaphore */ 8589580Smsmith#define GDT_IRQEN 0xff5 /* u_int8_t, board interrupts enable */ 8689580Smsmith#define GDT_EVENT 0xff8 /* u_int8_t, release event */ 8789580Smsmith#define GDT_IRQDEL 0xffc /* u_int8_t, acknowledge board interrupt */ 8889580Smsmith#define GDT_DPRAM_SZ 0x1000 8989580Smsmith 9089580Smsmith/* PLX register structure (new PCI controllers) */ 9189580Smsmith#define GDT_CFG_REG 0x00 /* u_int8_t, DPRAM cfg. (2: < 1MB, 0: any) */ 9289580Smsmith#define GDT_SEMA0_REG 0x40 /* volatile u_int8_t, command semaphore */ 9389580Smsmith#define GDT_SEMA1_REG 0x41 /* volatile u_int8_t, status semaphore */ 9489580Smsmith#define GDT_PLX_STATUS 0x44 /* volatile u_int16_t, command status */ 9589580Smsmith#define GDT_PLX_SERVICE 0x46 /* u_int16_t, service */ 9689580Smsmith#define GDT_PLX_INFO 0x48 /* u_int32_t [2], additional info */ 9789580Smsmith#define GDT_LDOOR_REG 0x60 /* u_int8_t, PCI to local doorbell */ 9889580Smsmith#define GDT_EDOOR_REG 0x64 /* volatile u_int8_t, local to PCI doorbell */ 9989580Smsmith#define GDT_CONTROL0 0x68 /* u_int8_t, control0 register (unused) */ 10089580Smsmith#define GDT_CONTROL1 0x69 /* u_int8_t, board interrupts enable */ 10189580Smsmith#define GDT_PLX_SZ 0x80 10289580Smsmith 10389580Smsmith/* DPRAM new PCI controllers */ 10489580Smsmith#define GDT_IC 0x00 /* interface */ 10589580Smsmith#define GDT_PCINEW_6SR (0x4000 - GDT_SRAM_SZ) 10689580Smsmith /* SRAM structure */ 10789580Smsmith#define GDT_PCINEW_SZ 0x4000 10889580Smsmith 10989580Smsmith/* i960 register structure (PCI MPR controllers) */ 11089580Smsmith#define GDT_MPR_SEMA0 0x10 /* volatile u_int8_t, command semaphore */ 11189580Smsmith#define GDT_MPR_SEMA1 0x12 /* volatile u_int8_t, status semaphore */ 11289580Smsmith#define GDT_MPR_STATUS 0x14 /* volatile u_int16_t, command status */ 11389580Smsmith#define GDT_MPR_SERVICE 0x16 /* u_int16_t, service */ 11489580Smsmith#define GDT_MPR_INFO 0x18 /* u_int32_t [2], additional info */ 11589580Smsmith#define GDT_MPR_LDOOR 0x20 /* u_int8_t, PCI to local doorbell */ 11689580Smsmith#define GDT_MPR_EDOOR 0x2c /* volatile u_int8_t, locl to PCI doorbell */ 11789580Smsmith#define GDT_EDOOR_EN 0x34 /* u_int8_t, board interrupts enable */ 11889580Smsmith#define GDT_SEVERITY 0xefc /* u_int8_t, event severity */ 11989580Smsmith#define GDT_EVT_BUF 0xf00 /* u_int8_t [256], event buffer */ 12089580Smsmith#define GDT_I960_SZ 0x1000 12189580Smsmith 12289580Smsmith/* DPRAM PCI MPR controllers */ 12389580Smsmith#define GDT_I960R 0x00 /* 4KB i960 registers */ 12489580Smsmith#define GDT_MPR_IC GDT_I960_SZ 12589580Smsmith /* i960 register area */ 12689580Smsmith#define GDT_MPR_6SR (GDT_I960_SZ + 0x3000 - GDT_SRAM_SZ) 12789580Smsmith /* DPRAM struct. */ 12889580Smsmith#define GDT_MPR_SZ (0x3000 - GDT_SRAM_SZ) 12989580Smsmith 13092739Salfredstatic int iir_pci_probe(device_t dev); 13192739Salfredstatic int iir_pci_attach(device_t dev); 13289580Smsmith 13392739Salfredvoid gdt_pci_enable_intr(struct gdt_softc *); 13489580Smsmith 13592739Salfredvoid gdt_mpr_copy_cmd(struct gdt_softc *, struct gdt_ccb *); 13692739Salfredu_int8_t gdt_mpr_get_status(struct gdt_softc *); 13792739Salfredvoid gdt_mpr_intr(struct gdt_softc *, struct gdt_intr_ctx *); 13892739Salfredvoid gdt_mpr_release_event(struct gdt_softc *); 13992739Salfredvoid gdt_mpr_set_sema0(struct gdt_softc *); 14092739Salfredint gdt_mpr_test_busy(struct gdt_softc *); 14189580Smsmith 14289580Smsmithstatic device_method_t iir_pci_methods[] = { 14389580Smsmith /* Device interface */ 14489580Smsmith DEVMETHOD(device_probe, iir_pci_probe), 14589580Smsmith DEVMETHOD(device_attach, iir_pci_attach), 14689580Smsmith { 0, 0} 14789580Smsmith}; 14889580Smsmith 14989580Smsmith 15089580Smsmithstatic driver_t iir_pci_driver = 15189580Smsmith{ 15289580Smsmith "iir", 15389580Smsmith iir_pci_methods, 15489580Smsmith sizeof(struct gdt_softc) 15589580Smsmith}; 15689580Smsmith 15789580Smsmithstatic devclass_t iir_devclass; 15889580Smsmith 15989580SmsmithDRIVER_MODULE(iir, pci, iir_pci_driver, iir_devclass, 0, 0); 160165102SmjacobMODULE_DEPEND(iir, pci, 1, 1, 1); 161165102SmjacobMODULE_DEPEND(iir, cam, 1, 1, 1); 16289580Smsmith 16389580Smsmithstatic int 16489580Smsmithiir_pci_probe(device_t dev) 16589580Smsmith{ 166254379Sjkim if (pci_get_vendor(dev) == INTEL_VENDOR_ID_IIR && 16789580Smsmith pci_get_device(dev) == INTEL_DEVICE_ID_IIR) { 16889580Smsmith device_set_desc(dev, "Intel Integrated RAID Controller"); 169143160Simp return (BUS_PROBE_DEFAULT); 17089580Smsmith } 17189580Smsmith if (pci_get_vendor(dev) == GDT_VENDOR_ID && 17289580Smsmith ((pci_get_device(dev) >= GDT_DEVICE_ID_MIN && 17389580Smsmith pci_get_device(dev) <= GDT_DEVICE_ID_MAX) || 17489580Smsmith pci_get_device(dev) == GDT_DEVICE_ID_NEWRX)) { 17589580Smsmith device_set_desc(dev, "ICP Disk Array Controller"); 176143160Simp return (BUS_PROBE_DEFAULT); 17789580Smsmith } 17889580Smsmith return (ENXIO); 17989580Smsmith} 18089580Smsmith 18189580Smsmith 18289580Smsmithstatic int 18389580Smsmithiir_pci_attach(device_t dev) 18489580Smsmith{ 18589580Smsmith struct gdt_softc *gdt; 186275975Ssmh struct resource *irq = NULL; 18789580Smsmith int retries, rid, error = 0; 18889580Smsmith void *ih; 18989580Smsmith u_int8_t protocol; 190275975Ssmh 191275975Ssmh gdt = device_get_softc(dev); 192275975Ssmh mtx_init(&gdt->sc_lock, "iir", NULL, MTX_DEF); 193275975Ssmh 19489580Smsmith /* map DPMEM */ 19589580Smsmith rid = PCI_DPMEM; 196275975Ssmh gdt->sc_dpmem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); 197275975Ssmh if (gdt->sc_dpmem == NULL) { 19889580Smsmith device_printf(dev, "can't allocate register resources\n"); 19989580Smsmith error = ENOMEM; 20089580Smsmith goto err; 20189580Smsmith } 20289580Smsmith 20389580Smsmith /* get IRQ */ 20489580Smsmith rid = 0; 205127135Snjl irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 206127135Snjl RF_ACTIVE | RF_SHAREABLE); 207192097Sbrueffer if (irq == NULL) { 20889580Smsmith device_printf(dev, "can't find IRQ value\n"); 20989580Smsmith error = ENOMEM; 21089580Smsmith goto err; 21189580Smsmith } 21289580Smsmith 213170872Sscottl gdt->sc_devnode = dev; 21489580Smsmith gdt->sc_init_level = 0; 21589580Smsmith gdt->sc_hanum = device_get_unit(dev); 21689580Smsmith gdt->sc_bus = pci_get_bus(dev); 21789580Smsmith gdt->sc_slot = pci_get_slot(dev); 218114001Sscottl gdt->sc_vendor = pci_get_vendor(dev); 21989580Smsmith gdt->sc_device = pci_get_device(dev); 22089580Smsmith gdt->sc_subdevice = pci_get_subdevice(dev); 22189580Smsmith gdt->sc_class = GDT_MPR; 22289580Smsmith/* no FC ctr. 22389580Smsmith if (gdt->sc_device >= GDT_PCI_PRODUCT_FC) 22489580Smsmith gdt->sc_class |= GDT_FC; 22589580Smsmith*/ 22689580Smsmith 22789580Smsmith /* initialize RP controller */ 22889580Smsmith /* check and reset interface area */ 229275975Ssmh bus_write_4(gdt->sc_dpmem, GDT_MPR_IC, htole32(GDT_MPR_MAGIC)); 230275975Ssmh if (bus_read_4(gdt->sc_dpmem, GDT_MPR_IC) != htole32(GDT_MPR_MAGIC)) { 231275975Ssmh device_printf(dev, "cannot access DPMEM at 0x%lx (shadowed?)\n", 232275975Ssmh rman_get_start(gdt->sc_dpmem)); 23389580Smsmith error = ENXIO; 23489580Smsmith goto err; 23589580Smsmith } 236275975Ssmh bus_set_region_4(gdt->sc_dpmem, GDT_I960_SZ, htole32(0), GDT_MPR_SZ >> 2); 23789580Smsmith 23889580Smsmith /* Disable everything */ 239275975Ssmh bus_write_1(gdt->sc_dpmem, GDT_EDOOR_EN, 240275975Ssmh bus_read_1(gdt->sc_dpmem, GDT_EDOOR_EN) | 4); 241275975Ssmh bus_write_1(gdt->sc_dpmem, GDT_MPR_EDOOR, 0xff); 242275975Ssmh bus_write_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_STATUS, 0); 243275975Ssmh bus_write_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_CMD_INDEX, 0); 24489580Smsmith 245275975Ssmh bus_write_4(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_INFO, 246275975Ssmh htole32(rman_get_start(gdt->sc_dpmem))); 247275975Ssmh bus_write_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_CMD_INDX, 0xff); 248275975Ssmh bus_write_1(gdt->sc_dpmem, GDT_MPR_LDOOR, 1); 24989580Smsmith 25089580Smsmith DELAY(20); 25189580Smsmith retries = GDT_RETRIES; 252275975Ssmh while (bus_read_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_STATUS) != 0xff) { 25389580Smsmith if (--retries == 0) { 254275975Ssmh device_printf(dev, "DEINIT failed\n"); 25589580Smsmith error = ENXIO; 25689580Smsmith goto err; 25789580Smsmith } 25889580Smsmith DELAY(1); 25989580Smsmith } 26089580Smsmith 261275975Ssmh protocol = (uint8_t)le32toh(bus_read_4(gdt->sc_dpmem, 262275975Ssmh GDT_MPR_IC + GDT_S_INFO)); 263275975Ssmh bus_write_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_STATUS, 0); 26489580Smsmith if (protocol != GDT_PROTOCOL_VERSION) { 265275975Ssmh device_printf(dev, "unsupported protocol %d\n", protocol); 26689580Smsmith error = ENXIO; 26789580Smsmith goto err; 26889580Smsmith } 26989580Smsmith 270275975Ssmh /* special command to controller BIOS */ 271275975Ssmh bus_write_4(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_INFO, htole32(0)); 272275975Ssmh bus_write_4(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_INFO + sizeof (u_int32_t), 273275975Ssmh htole32(0)); 274275975Ssmh bus_write_4(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_INFO + 2 * sizeof (u_int32_t), 275275975Ssmh htole32(1)); 276275975Ssmh bus_write_4(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_INFO + 3 * sizeof (u_int32_t), 277275975Ssmh htole32(0)); 278275975Ssmh bus_write_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_CMD_INDX, 0xfe); 279275975Ssmh bus_write_1(gdt->sc_dpmem, GDT_MPR_LDOOR, 1); 28089580Smsmith 28189580Smsmith DELAY(20); 28289580Smsmith retries = GDT_RETRIES; 283275975Ssmh while (bus_read_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_STATUS) != 0xfe) { 28489580Smsmith if (--retries == 0) { 285275975Ssmh device_printf(dev, "initialization error\n"); 28689580Smsmith error = ENXIO; 28789580Smsmith goto err; 28889580Smsmith } 28989580Smsmith DELAY(1); 29089580Smsmith } 29189580Smsmith 292275975Ssmh bus_write_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_STATUS, 0); 29389580Smsmith 29489580Smsmith gdt->sc_ic_all_size = GDT_MPR_SZ; 29589580Smsmith 29689580Smsmith gdt->sc_copy_cmd = gdt_mpr_copy_cmd; 29789580Smsmith gdt->sc_get_status = gdt_mpr_get_status; 29889580Smsmith gdt->sc_intr = gdt_mpr_intr; 29989580Smsmith gdt->sc_release_event = gdt_mpr_release_event; 30089580Smsmith gdt->sc_set_sema0 = gdt_mpr_set_sema0; 30189580Smsmith gdt->sc_test_busy = gdt_mpr_test_busy; 30289580Smsmith 30389580Smsmith /* Allocate a dmatag representing the capabilities of this attachment */ 304232854Sscottl if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(dev), 305232854Sscottl /*alignemnt*/1, /*boundary*/0, 30689580Smsmith /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 30789580Smsmith /*highaddr*/BUS_SPACE_MAXADDR, 30889580Smsmith /*filter*/NULL, /*filterarg*/NULL, 30989580Smsmith /*maxsize*/BUS_SPACE_MAXSIZE_32BIT, 310281826Smav /*nsegments*/BUS_SPACE_UNRESTRICTED, 31189580Smsmith /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, 312117126Sscottl /*flags*/0, /*lockfunc*/busdma_lock_mutex, 313275975Ssmh /*lockarg*/&gdt->sc_lock, &gdt->sc_parent_dmat) != 0) { 31489580Smsmith error = ENXIO; 31589580Smsmith goto err; 31689580Smsmith } 31789580Smsmith gdt->sc_init_level++; 31889580Smsmith 31989580Smsmith if (iir_init(gdt) != 0) { 32089580Smsmith iir_free(gdt); 32189580Smsmith error = ENXIO; 32289580Smsmith goto err; 32389580Smsmith } 32489580Smsmith 32589580Smsmith /* Register with the XPT */ 32689580Smsmith iir_attach(gdt); 32789580Smsmith 32889580Smsmith /* associate interrupt handler */ 329275975Ssmh if (bus_setup_intr(dev, irq, INTR_TYPE_CAM | INTR_MPSAFE, 330166901Spiso NULL, iir_intr, gdt, &ih )) { 33189580Smsmith device_printf(dev, "Unable to register interrupt handler\n"); 33289580Smsmith error = ENXIO; 33389580Smsmith goto err; 33489580Smsmith } 33589580Smsmith 33689580Smsmith gdt_pci_enable_intr(gdt); 33789580Smsmith return (0); 33889580Smsmith 33989580Smsmitherr: 34089580Smsmith if (irq) 34189580Smsmith bus_release_resource( dev, SYS_RES_IRQ, 0, irq ); 342275975Ssmh 343275975Ssmh if (gdt->sc_dpmem) 344275975Ssmh bus_release_resource( dev, SYS_RES_MEMORY, rid, gdt->sc_dpmem ); 345275975Ssmh mtx_destroy(&gdt->sc_lock); 346275975Ssmh 34789580Smsmith return (error); 34889580Smsmith} 34989580Smsmith 35089580Smsmith 35189580Smsmith/* Enable interrupts */ 35289580Smsmithvoid 35389580Smsmithgdt_pci_enable_intr(struct gdt_softc *gdt) 35489580Smsmith{ 35589580Smsmith GDT_DPRINTF(GDT_D_INTR, ("gdt_pci_enable_intr(%p) ", gdt)); 35689580Smsmith 35789580Smsmith switch(GDT_CLASS(gdt)) { 35889580Smsmith case GDT_MPR: 359275975Ssmh bus_write_1(gdt->sc_dpmem, GDT_MPR_EDOOR, 0xff); 360275975Ssmh bus_write_1(gdt->sc_dpmem, GDT_EDOOR_EN, 361275975Ssmh bus_read_1(gdt->sc_dpmem, GDT_EDOOR_EN) & ~4); 36289580Smsmith break; 36389580Smsmith } 36489580Smsmith} 36589580Smsmith 36689580Smsmith 36789580Smsmith/* 36889580Smsmith * MPR PCI controller-specific functions 36989580Smsmith */ 37089580Smsmith 37189580Smsmithvoid 372156139Sscottlgdt_mpr_copy_cmd(struct gdt_softc *gdt, struct gdt_ccb *gccb) 37389580Smsmith{ 374156139Sscottl u_int16_t cp_count = roundup(gccb->gc_cmd_len, sizeof (u_int32_t)); 37589580Smsmith u_int16_t dp_offset = gdt->sc_cmd_off; 37689580Smsmith u_int16_t cmd_no = gdt->sc_cmd_cnt++; 37789580Smsmith 37889580Smsmith GDT_DPRINTF(GDT_D_CMD, ("gdt_mpr_copy_cmd(%p) ", gdt)); 37989580Smsmith 38089580Smsmith gdt->sc_cmd_off += cp_count; 38189580Smsmith 382275975Ssmh bus_write_region_4(gdt->sc_dpmem, GDT_MPR_IC + GDT_DPR_CMD + dp_offset, 383275975Ssmh (u_int32_t *)gccb->gc_cmd, cp_count >> 2); 384275975Ssmh bus_write_2(gdt->sc_dpmem, 385275975Ssmh GDT_MPR_IC + GDT_COMM_QUEUE + cmd_no * GDT_COMM_Q_SZ + GDT_OFFSET, 386275975Ssmh htole16(GDT_DPMEM_COMMAND_OFFSET + dp_offset)); 387275975Ssmh bus_write_2(gdt->sc_dpmem, 388275975Ssmh GDT_MPR_IC + GDT_COMM_QUEUE + cmd_no * GDT_COMM_Q_SZ + GDT_SERV_ID, 389275975Ssmh htole16(gccb->gc_service)); 39089580Smsmith} 39189580Smsmith 39289580Smsmithu_int8_t 39389580Smsmithgdt_mpr_get_status(struct gdt_softc *gdt) 39489580Smsmith{ 39589580Smsmith GDT_DPRINTF(GDT_D_MISC, ("gdt_mpr_get_status(%p) ", gdt)); 39689580Smsmith 397275975Ssmh return bus_read_1(gdt->sc_dpmem, GDT_MPR_EDOOR); 39889580Smsmith} 39989580Smsmith 40089580Smsmithvoid 40189580Smsmithgdt_mpr_intr(struct gdt_softc *gdt, struct gdt_intr_ctx *ctx) 40289580Smsmith{ 40389580Smsmith int i; 40489580Smsmith 40589580Smsmith GDT_DPRINTF(GDT_D_INTR, ("gdt_mpr_intr(%p) ", gdt)); 40689580Smsmith 407275975Ssmh bus_write_1(gdt->sc_dpmem, GDT_MPR_EDOOR, 0xff); 408156139Sscottl 40989580Smsmith if (ctx->istatus & 0x80) { /* error flag */ 41089580Smsmith ctx->istatus &= ~0x80; 411275975Ssmh ctx->cmd_status = bus_read_2(gdt->sc_dpmem, GDT_MPR_STATUS); 41289580Smsmith } else /* no error */ 41389580Smsmith ctx->cmd_status = GDT_S_OK; 41489580Smsmith 415275975Ssmh ctx->info = bus_read_4(gdt->sc_dpmem, GDT_MPR_INFO); 416275975Ssmh ctx->service = bus_read_2(gdt->sc_dpmem, GDT_MPR_SERVICE); 417275975Ssmh ctx->info2 = bus_read_4(gdt->sc_dpmem, GDT_MPR_INFO + sizeof (u_int32_t)); 41889580Smsmith 41989580Smsmith /* event string */ 42089580Smsmith if (ctx->istatus == GDT_ASYNCINDEX) { 42189580Smsmith if (ctx->service != GDT_SCREENSERVICE && 42289580Smsmith (gdt->sc_fw_vers & 0xff) >= 0x1a) { 423275975Ssmh gdt->sc_dvr.severity = bus_read_1(gdt->sc_dpmem, GDT_SEVERITY); 42489580Smsmith for (i = 0; i < 256; ++i) { 425275975Ssmh gdt->sc_dvr.event_string[i] = bus_read_1(gdt->sc_dpmem, 426275975Ssmh GDT_EVT_BUF + i); 42789580Smsmith if (gdt->sc_dvr.event_string[i] == 0) 42889580Smsmith break; 42989580Smsmith } 43089580Smsmith } 43189580Smsmith } 432275975Ssmh bus_write_1(gdt->sc_dpmem, GDT_MPR_SEMA1, 0); 43389580Smsmith} 43489580Smsmith 43589580Smsmithvoid 43689580Smsmithgdt_mpr_release_event(struct gdt_softc *gdt) 43789580Smsmith{ 43889580Smsmith GDT_DPRINTF(GDT_D_MISC, ("gdt_mpr_release_event(%p) ", gdt)); 43989580Smsmith 440275975Ssmh bus_write_1(gdt->sc_dpmem, GDT_MPR_LDOOR, 1); 44189580Smsmith} 44289580Smsmith 44389580Smsmithvoid 44489580Smsmithgdt_mpr_set_sema0(struct gdt_softc *gdt) 44589580Smsmith{ 44689580Smsmith GDT_DPRINTF(GDT_D_MISC, ("gdt_mpr_set_sema0(%p) ", gdt)); 44789580Smsmith 448275975Ssmh bus_write_1(gdt->sc_dpmem, GDT_MPR_SEMA0, 1); 44989580Smsmith} 45089580Smsmith 45189580Smsmithint 45289580Smsmithgdt_mpr_test_busy(struct gdt_softc *gdt) 45389580Smsmith{ 45489580Smsmith GDT_DPRINTF(GDT_D_MISC, ("gdt_mpr_test_busy(%p) ", gdt)); 45589580Smsmith 456275975Ssmh return (bus_read_1(gdt->sc_dpmem, GDT_MPR_SEMA0) & 1); 45789580Smsmith} 458