From 5d7561656a2ec6b5511fb174aaef518d2e64eebe Mon Sep 17 00:00:00 2001 From: joerg Date: Sat, 23 Jan 2010 07:54:06 +0000 Subject: Overhaul of the pcii driver: . Properly allocate all IO space resources. These cards scatter their IO addresses over a range of 0x1600 bytes, and they require an additional address for "special interrupt handling". . Implement the "special interrupt handling" per the GPIB-PCIIA Technical Reference Manual; this was apparently not declared for the clone card this driver has been originally implemented for, but it turned out to be needed for both, an original NI brand PCII/PCIIA card as well as the Axiom AX5488 clone. . Add some diagnostic messages for various resource allocation etc. failures during probe. . Add some comments about the structure of the IO address space that is used by these cards. MFC after: 1 day --- sys/dev/ieee488/upd7210.c | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) (limited to 'sys/dev/ieee488/upd7210.c') diff --git a/sys/dev/ieee488/upd7210.c b/sys/dev/ieee488/upd7210.c index 27359e2..2c63f2f 100644 --- a/sys/dev/ieee488/upd7210.c +++ b/sys/dev/ieee488/upd7210.c @@ -1,5 +1,6 @@ /*- * Copyright (c) 2005 Poul-Henning Kamp + * Copyright (c) 2010 Joerg Wunsch * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -71,7 +72,7 @@ upd7210_rd(struct upd7210 *u, enum upd7210_rreg reg) { u_int r; - r = bus_read_1(u->reg_res[reg], u->reg_offset[reg]); + r = bus_read_1(u->reg_res[reg], 0); u->rreg[reg] = r; return (r); } @@ -80,7 +81,7 @@ void upd7210_wr(struct upd7210 *u, enum upd7210_wreg reg, u_int val) { - bus_write_1(u->reg_res[reg], u->reg_offset[reg], val); + bus_write_1(u->reg_res[reg], 0, val); u->wreg[reg] = val; if (reg == AUXMR) u->wreg[8 + (val >> 5)] = val & 0x1f; @@ -96,19 +97,35 @@ upd7210intr(void *arg) mtx_lock(&u->mutex); isr1 = upd7210_rd(u, ISR1); isr2 = upd7210_rd(u, ISR2); - if (u->busy == 0 || u->irq == NULL || !u->irq(u, 1)) { + if (isr1 != 0 || isr2 != 0) { + if (u->busy == 0 || u->irq == NULL || !u->irq(u, 1)) { #if 0 - printf("upd7210intr [%02x %02x %02x", - upd7210_rd(u, DIR), isr1, isr2); - printf(" %02x %02x %02x %02x %02x] ", - upd7210_rd(u, SPSR), - upd7210_rd(u, ADSR), - upd7210_rd(u, CPTR), - upd7210_rd(u, ADR0), + printf("upd7210intr [%02x %02x %02x", + upd7210_rd(u, DIR), isr1, isr2); + printf(" %02x %02x %02x %02x %02x] ", + upd7210_rd(u, SPSR), + upd7210_rd(u, ADSR), + upd7210_rd(u, CPTR), + upd7210_rd(u, ADR0), upd7210_rd(u, ADR1)); - upd7210_print_isr(isr1, isr2); - printf("\n"); + upd7210_print_isr(isr1, isr2); + printf("\n"); #endif + } + /* + * "special interrupt handling" + * + * In order to implement shared IRQs, the original + * PCIIa uses IO locations 0x2f0 + (IRQ#) as an output + * location. If an ISR for a particular card has + * detected this card triggered the IRQ, it must reset + * the card's IRQ by writing (anything) to that IO + * location. + * + * Some clones apparently don't implement this + * feature, but National Instrument cards do. + */ + bus_write_1(u->irq_clear_res, 0, 42); } mtx_unlock(&u->mutex); } -- cgit v1.1