diff options
author | 1996-06-27 21:15:44 +0000 | |
---|---|---|
committer | 1996-06-27 21:15:44 +0000 | |
commit | 772afd3a90efd893cbbe788a45221b31e180bdf4 (patch) | |
tree | 9d788aabb547a112bcb5afb5e5a6e07bdea8de61 | |
parent | We now support bug reports using a modified version of send-pr(1) that (diff) | |
download | wireguard-openbsd-772afd3a90efd893cbbe788a45221b31e180bdf4.tar.xz wireguard-openbsd-772afd3a90efd893cbbe788a45221b31e180bdf4.zip |
new 2940 driver merged from freebsd sources 960623
-rw-r--r-- | sys/dev/eisa/ahc_eisa.c | 7 | ||||
-rw-r--r-- | sys/dev/eisa/aic7770.c | 298 | ||||
-rw-r--r-- | sys/dev/ic/93cx6.c | 120 | ||||
-rw-r--r-- | sys/dev/ic/93cx6.h | 46 | ||||
-rw-r--r-- | sys/dev/ic/aic7xxx.c | 474 | ||||
-rw-r--r-- | sys/dev/ic/aic7xxxreg.h | 11 | ||||
-rw-r--r-- | sys/dev/ic/aic7xxxvar.h | 29 | ||||
-rw-r--r-- | sys/dev/ic/smc93cx6.c | 47 | ||||
-rw-r--r-- | sys/dev/ic/smc93cx6var.h | 15 | ||||
-rw-r--r-- | sys/dev/isa/lpt.c | 13 | ||||
-rw-r--r-- | sys/dev/microcode/aic7xxx/aic7xxx.seq | 55 | ||||
-rw-r--r-- | sys/dev/microcode/aic7xxx/aic7xxx_asm.1 | 2 | ||||
-rw-r--r-- | sys/dev/microcode/aic7xxx/aic7xxx_asm.c | 4 | ||||
-rw-r--r-- | sys/dev/microcode/aic7xxx/aic7xxx_reg.h | 16 | ||||
-rw-r--r-- | sys/dev/pci/ahc_pci.c | 93 |
15 files changed, 583 insertions, 647 deletions
diff --git a/sys/dev/eisa/ahc_eisa.c b/sys/dev/eisa/ahc_eisa.c index ef1fa58c7f1..994ed19cf28 100644 --- a/sys/dev/eisa/ahc_eisa.c +++ b/sys/dev/eisa/ahc_eisa.c @@ -1,5 +1,3 @@ -/* $NetBSD: ahc_eisa.c,v 1.4 1996/05/20 00:55:44 thorpej Exp $ */ - /* * Product specific probe and attach routines for: * 27/284X and aic7770 motherboard SCSI controllers @@ -30,6 +28,8 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. + * + * $Id: ahc_eisa.c,v 1.2 1996/06/27 21:15:44 shawn Exp $ */ #if defined(__FreeBSD__) @@ -371,8 +371,7 @@ ahc_eisa_attach(parent, self, aux) * usefull for debugging irq problems */ if(bootverbose) { - printf( - "%s: Using %s Interrupts\n", + printf("%s: Using %s Interrupts\n", ahc_name(ahc), ahc->pause & IRQMS ? "Level Sensitive" : "Edge Triggered"); diff --git a/sys/dev/eisa/aic7770.c b/sys/dev/eisa/aic7770.c index 6f56b0ed28c..b7aea8278a9 100644 --- a/sys/dev/eisa/aic7770.c +++ b/sys/dev/eisa/aic7770.c @@ -2,7 +2,7 @@ * Product specific probe and attach routines for: * 27/284X and aic7770 motherboard SCSI controllers * - * Copyright (c) 1995, 1996 Justin T. Gibbs. + * Copyright (c) 1994, 1995, 1996 Justin T. Gibbs. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: aic7770.c,v 1.1 1996/05/05 12:42:22 deraadt Exp $ + * $Id: aic7770.c,v 1.2 1996/06/27 21:15:45 shawn Exp $ */ #if defined(__FreeBSD__) @@ -46,14 +46,8 @@ #if defined(__NetBSD__) #include <sys/device.h> -#if NetBSD1_1 < 3 /* NetBSD-1.1 */ -#include <machine/pio.h> -#else #include <machine/bus.h> -#ifdef __alpha__ #include <machine/intr.h> -#endif -#endif #endif /* defined(__NetBSD__) */ #include <scsi/scsi_all.h> @@ -74,31 +68,12 @@ #elif defined(__NetBSD__) -#if NetBSD1_1 < 3 /* NetBSD-1.1 */ -#include <dev/isa/isareg.h> -#include <dev/isa/isavar.h> -#include <dev/isa/isadmavar.h> - -/* Standard EISA Host ID regs (Offset from slot base) */ -#define HID0 0x80 /* 0,1: msb of ID2, 2-7: ID1 */ -#define HID1 0x81 /* 0-4: ID3, 5-7: LSB ID2 */ -#define HID2 0x82 /* product */ -#define HID3 0x83 /* firmware revision */ - -#define CHAR1(B1,B2) (((B1>>2) & 0x1F) | '@') -#define CHAR2(B1,B2) (((B1<<3) & 0x18) | ((B2>>5) & 0x7)|'@') -#define CHAR3(B1,B2) ((B2 & 0x1F) | '@') - -#define EISA_MAX_SLOTS 16 /* XXX should be defined in a common header */ -static ahc_slot = 0; /* slot last board was found in */ -#else #include <dev/eisa/eisareg.h> #include <dev/eisa/eisavar.h> #include <dev/eisa/eisadevs.h> -#endif +#include <dev/ic/aic7xxxreg.h> #include <dev/ic/aic7xxxvar.h> -#include <dev/microcode/aic7xxx/aic7xxx_reg.h> #endif /* defined(__NetBSD__) */ @@ -214,137 +189,26 @@ aic7770probe(void) #define bootverbose 1 -int ahe_irq __P((bus_chipset_tag_t, bus_io_handle_t)); -int ahematch __P((struct device *, void *, void *)); -void aheattach __P((struct device *, struct device *, void *)); - -#if NetBSD1_1 < 3 /* NetBSD-1.1 */ - -int aheprobe1 __P((struct ahc_data *, struct isa_attach_args *, int)); -int aheprobe __P((struct device *, void *, void *)); - -struct cfdriver ahecd = { - NULL, "ahe", aheprobe, aheattach, DV_DULL, - sizeof(struct ahc_data) -}; - -int -aheprobe1(ahc, ia, iobase) - struct ahc_data *ahc; - struct isa_attach_args *ia; - int iobase; -{ - int i, irq; - u_char intdef, sig_id[4]; - - static struct { - ahc_type type; - u_int8_t id; - } valid_ids[] = { - /* Entries of other tested adaptors should be added here */ - { AHC_AIC7770, 0x70 }, /*aic7770 on Motherboard*/ - { AHC_274, 0x71 }, /*274x*/ - { AHC_284, 0x56 }, /*284x, BIOS enabled*/ - { AHC_284, 0x57 } /*284x, BIOS disabled*/ - }; - - for (i = 0; i < sizeof(sig_id); i++) { - /* - * An outb is required to prime these - * registers on VL cards - */ - outb(iobase + HID0, HID0 + i); - sig_id[i] = inb(iobase + HID0 + i); - } - if (sig_id[0] == 0xff) - return (0); - /* Check manufacturer's ID. */ - if (CHAR1(sig_id[0], sig_id[1]) != 'A' || - CHAR2(sig_id[0], sig_id[1]) != 'D' || - CHAR3(sig_id[0], sig_id[1]) != 'P' || - sig_id[2] != 0x77) - return (0); - for (i = 0; i < sizeof(valid_ids)/sizeof(valid_ids[0]); i++) { - if (sig_id[3] != valid_ids[i].id) - continue; - - ahc_reset("ahe", 0, iobase); - intdef = inb(INTDEF + iobase); - switch (irq = (intdef & 0xf)) { - case 9: - case 10: - case 11: - case 12: - case 14: - case 15: - break; - default: - printf("%s: illegal irq setting %d\n", - ahc->sc_dev.dv_xname, intdef); - return (0); - } - - if (ia->ia_irq == IRQUNK) { - ia->ia_irq = irq; - } else if (ia->ia_irq != irq) { - printf("%s: irq mismatch; kernel configured %d" - "!= board configured %d\n", - ahc->sc_dev.dv_xname, ia->ia_irq, irq); - return (0); - } - - ahc->type = valid_ids[i].type; - - ia->ia_msize = 0; - ia->ia_iobase = iobase; - ia->ia_iosize = AHC_EISA_IOSIZE; - return (1); - } - return (0); -} +int ahc_eisa_match __P((struct device *, void *, void *)); +void ahc_eisa_attach __P((struct device *, struct device *, void *)); -int -aheprobe(parent, match, aux) - struct device *parent; - void *match, *aux; -{ - struct isa_attach_args *ia = aux; - struct ahc_data *ahc = match; - - if (ia->ia_iobase != IOBASEUNK) - return aheprobe1(ahc, ia, ia->ia_iobase); - - ahc_slot++; - for (; ahc_slot < EISA_MAX_SLOTS; ahc_slot++) { - if (aheprobe1(ahc, ia, - 0x1000 * ahc_slot + AHC_EISA_SLOT_OFFSET)) - return 1; - } - return (0); -} -#else - -struct cfattach ahe_ca = { - sizeof(struct ahc_data), ahematch, aheattach -}; - -struct cfdriver ahe_cd = { - NULL, "ahe", DV_DULL +struct cfattach ahc_eisa_ca = { + sizeof(struct ahc_data), ahc_eisa_match, ahc_eisa_attach }; /* * Return irq setting of the board, otherwise -1. */ int -ahe_irq(bc, ioh) +ahc_eisa_irq(bc, ioh) bus_chipset_tag_t bc; bus_io_handle_t ioh; { int irq; u_char intdef; - ahc_reset("ahe", bc, ioh); + ahc_reset("ahc_eisa", bc, ioh); intdef = bus_io_read_1(bc, ioh, INTDEF); switch (irq = (intdef & 0xf)) { case 9: @@ -355,7 +219,7 @@ ahe_irq(bc, ioh) case 15: break; default: - printf("ahe_irq: illegal irq setting %d\n", intdef); + printf("ahc_eisa_irq: illegal irq setting %d\n", intdef); return -1; } @@ -369,11 +233,12 @@ ahe_irq(bc, ioh) * the actual probe routine to check it out. */ int -ahematch(parent, match, aux) +ahc_eisa_match(parent, match, aux) struct device *parent; void *match, *aux; { struct eisa_attach_args *ea = aux; + bus_chipset_tag_t bc = ea->ea_bc; bus_io_handle_t ioh; int irq; @@ -384,30 +249,17 @@ ahematch(parent, match, aux) strcmp(ea->ea_idstring, "ADP7757")) /* XXX - not EISA, but VL */ return (0); -#ifdef notyet - if (bus_io_map(ea->ea_bc, EISA_SLOT_ADDR(ea->ea_slot), EISA_SLOT_SIZE, - &ioh)) + if (bus_io_map(bc, EISA_SLOT_ADDR(ea->ea_slot) + AHC_EISA_SLOT_OFFSET, + AHC_EISA_IOSIZE, &ioh)) return (0); - /* This won't compile as-is, anyway. */ - bus_io_write_1(ea->ea_bc, ioh, EISA_CONTROL, EISA_ENABLE | EISA_RESET); - delay(10); - bus_io_write_1(ea->ea_bc, ioh, EISA_CONTROL, EISA_ENABLE); - /* Wait for reset? */ - delay(1000); - bus_io_unmap(ea->ea_bc, ioh, EISA_SLOT_SIZE); -#endif - if (bus_io_map(ea->ea_bc, - EISA_SLOT_ADDR(ea->ea_slot) + AHC_EISA_SLOT_OFFSET, - AHC_EISA_IOSIZE, &ioh)) - return (0); - irq = ahe_irq(ea->ea_bc, ioh); - bus_io_unmap(ea->ea_bc, ioh, EISA_SLOT_SIZE); + irq = ahc_eisa_irq(bc, ioh); + + bus_io_unmap(bc, ioh, AHC_EISA_IOSIZE); + return (irq >= 0); } -#endif - #endif /* defined(__NetBSD__) */ #if defined(__FreeBSD__) @@ -416,7 +268,7 @@ aic7770_attach(e_dev) struct eisa_device *e_dev; #elif defined(__NetBSD__) void -aheattach(parent, self, aux) +ahc_eisa_attach(parent, self, aux) struct device *parent, *self; void *aux; #endif @@ -461,8 +313,8 @@ aheattach(parent, self, aux) } /* - * The IRQMS bit enables level sensitive interrupts only allow - * IRQ sharing if its set. + * The IRQMS bit enables level sensitive interrupts. Only allow + * IRQ sharing if it's set. */ if(eisa_reg_intr(e_dev, irq, ahc_intr, (void *)ahc, &bio_imask, /*shared ==*/ahc->pause & IRQMS)) { @@ -474,40 +326,19 @@ aheattach(parent, self, aux) #elif defined(__NetBSD__) struct ahc_data *ahc = (void *)self; - const char *model; -#if NetBSD1_1 < 3 /* NetBSD-1.1 */ - struct isa_attach_args *ia = aux; - - switch (ahc->type) { - case AHC_AIC7770: - model = "AIC-7770 SCSI (on motherboard)"; - break; - case AHC_274: - model = "AHA-274x SCSI"; - break; - case AHC_284: - model = "AHA-284x SCSI"; - break; - default: - panic("aheattach: Unknown device type 0x%x\n", ahc->type); - } - printf(": %s\n", model); - - ahc_construct(ahc, ahc->sc_dev.dv_unit, 0, - ia->ia_iobase, ahc->type, AHC_FNONE); -#else struct eisa_attach_args *ea = aux; - bus_io_handle_t ioh; /* XXX - ioh */ - eisa_intr_handle_t ih; - const char *intrstr; + bus_chipset_tag_t bc = ea->ea_bc; + bus_io_handle_t ioh; int irq; + eisa_chipset_tag_t ec = ea->ea_ec; + eisa_intr_handle_t ih; + const char *model, *intrstr; - if (bus_io_map(ea->ea_bc, - EISA_SLOT_ADDR(ea->ea_slot) + AHC_EISA_SLOT_OFFSET, + if (bus_io_map(bc, EISA_SLOT_ADDR(ea->ea_slot) + AHC_EISA_SLOT_OFFSET, AHC_EISA_IOSIZE, &ioh)) - panic("aheattach: could not map I/O addresses"); - if ((irq = ahe_irq(ea->ea_bc, ioh)) < 0) - panic("aheattach: ahe_irq failed!"); + panic("ahc_eisa_attach: could not map I/O addresses"); + if ((irq = ahc_eisa_irq(bc, ioh)) < 0) + panic("ahc_eisa_attach: ahc_eisa_irq failed!"); if (strcmp(ea->ea_idstring, "ADP7770") == 0) { model = EISA_PRODUCT_ADP7770; @@ -522,19 +353,17 @@ aheattach(parent, self, aux) model = EISA_PRODUCT_ADP7757; type = AHC_284; } else { - panic("aheattach: Unknown device type %s\n", + panic("ahc_eisa_attach: Unknown device type %s\n", ea->ea_idstring); } printf(": %s\n", model); - ahc_construct(ahc, - ahc->sc_dev.dv_unit, ea->ea_bc, ioh, type, AHC_FNONE); - if (eisa_intr_map(ea->ea_ec, irq, &ih)) { + ahc_construct(ahc, bc, ioh, type, AHC_FNONE); + if (eisa_intr_map(ec, irq, &ih)) { printf("%s: couldn't map interrupt (%d)\n", ahc->sc_dev.dv_xname, irq); return; } -#endif #endif /* defined(__NetBSD__) */ /* @@ -542,14 +371,8 @@ aheattach(parent, self, aux) * usefull for debugging irq problems */ if(bootverbose) { - printf( -#if defined(__FreeBSD__) - "ahc%d: Using %s Interrupts\n", - unit, -#elif defined(__NetBSD__) - "%s: Using %s Interrupts\n", - ahc->sc_dev.dv_xname, -#endif + printf("%s: Using %s Interrupts\n", + ahc_name(ahc), ahc->pause & IRQMS ? "Level Sensitive" : "Edge Triggered"); } @@ -562,18 +385,14 @@ aheattach(parent, self, aux) */ switch( ahc->type ) { case AHC_AIC7770: - { - /* XXX - * It would be really nice to know if the BIOS - * was installed for the motherboard controllers, - * but I don't know how to yet. Assume its enabled - * for now. - */ - break; - } case AHC_274: { - if((AHC_INB(ahc, HA_274_BIOSCTRL) & BIOSMODE) == BIOSDISABLED) + u_char biosctrl = AHC_INB(ahc, HA_274_BIOSCTRL); + + /* Get the primary channel information */ + ahc->flags |= (biosctrl & CHANNEL_B_PRIMARY); + + if((biosctrl & BIOSMODE) == BIOSDISABLED) ahc->flags |= AHC_USEDEFAULTS; break; } @@ -597,7 +416,7 @@ aheattach(parent, self, aux) /* * See if we have a Rev E or higher aic7770. Anything below a * Rev E will have a R/O autoflush disable configuration bit. - * Its still not clear exactly what is differenent about the Rev E. + * It's still not clear exactly what is differenent about the Rev E. * We think it allows 8 bit entries in the QOUTFIFO to support * "paging" SCBs so you can have more than 4 commands active at * once. @@ -626,19 +445,11 @@ aheattach(parent, self, aux) else id_string = "aic7770 <= Rev C, "; -#if defined(__FreeBSD__) - printf("ahc%d: %s", unit, id_string); -#elif defined(__NetBSD__) - printf("%s: %s", ahc->sc_dev.dv_xname, id_string); -#endif + printf("%s: %s", ahc_name(ahc), id_string); } /* Setup the FIFO threshold and the bus off time */ - if(ahc->flags & AHC_USEDEFAULTS) { - AHC_OUTB(ahc, BUSSPD, DFTHRSH_100); - AHC_OUTB(ahc, BUSTIME, BOFF_60BCLKS); - } - else { + { u_char hostconf = AHC_INB(ahc, HOSTCONF); AHC_OUTB(ahc, BUSSPD, hostconf & DFTHRSH); AHC_OUTB(ahc, BUSTIME, (hostconf << 2) & BOFF); @@ -651,7 +462,7 @@ aheattach(parent, self, aux) #if defined(__FreeBSD__) ahc_free(ahc); /* - * The board's IRQ line is not yet enabled so its safe + * The board's IRQ line is not yet enabled so it's safe * to release the irq. */ eisa_release_intr(e_dev, irq, ahc_intr); @@ -679,25 +490,17 @@ aheattach(parent, self, aux) e_dev->kdc->kdc_state = DC_BUSY; /* host adapters always busy */ #elif defined(__NetBSD__) -#if NetBSD1_1 < 3 /* NetBSD-1.1 */ - ahc->sc_ih = isa_intr_establish(ia->ia_irq, - ahc->pause & IRQMS ? IST_LEVEL : IST_EDGE, ISA_IPL_BIO, - ahc_intr, ahc); -#else - intrstr = eisa_intr_string(ea->ea_ec, ih); + intrstr = eisa_intr_string(ec, ih); /* * The IRQMS bit enables level sensitive interrupts only allow * IRQ sharing if its set. */ + ahc->sc_ih = eisa_intr_establish(ec, ih, + ahc->pause & IRQMS ? IST_LEVEL : IST_EDGE, IPL_BIO, ahc_intr, ahc #ifdef __OpenBSD__ - ahc->sc_ih = eisa_intr_establish(ea->ea_ec, ih, - ahc->pause & IRQMS ? IST_LEVEL : IST_EDGE, IPL_BIO, - ahc_intr, ahc, ahc->sc_dev.dv_xname); -#else - ahc->sc_ih = eisa_intr_establish(ea->ea_ec, ih, - ahc->pause & IRQMS ? IST_LEVEL : IST_EDGE, IPL_BIO, - ahc_intr, ahc); + , ahc->sc_dev.dv_xname #endif + ); if (ahc->sc_ih == NULL) { printf("%s: couldn't establish interrupt", ahc->sc_dev.dv_xname); @@ -710,7 +513,6 @@ aheattach(parent, self, aux) if (intrstr != NULL) printf("%s: interrupting at %s\n", ahc->sc_dev.dv_xname, intrstr); -#endif #endif /* defined(__NetBSD__) */ /* Attach sub-devices - always succeeds */ diff --git a/sys/dev/ic/93cx6.c b/sys/dev/ic/93cx6.c index 89ac0343bde..5327d39d746 100644 --- a/sys/dev/ic/93cx6.c +++ b/sys/dev/ic/93cx6.c @@ -18,7 +18,7 @@ * 4. Modifications may be freely made to this file if the above conditions * are met. * - * $Id: 93cx6.c,v 1.1 1996/05/05 12:42:27 deraadt Exp $ + * $Id: 93cx6.c,v 1.2 1996/06/27 21:15:46 shawn Exp $ */ /* @@ -58,10 +58,9 @@ #if defined(__FreeBSD__) #include <machine/clock.h> #include <i386/scsi/93cx6.h> -#endif -#if defined(__NetBSD__) -#include <machine/pio.h> -#include <dev/ic/93cx6.h> +#elif defined(__NetBSD__) +#include <machine/bus.h> +#include <dev/ic/smc93cx6var.h> #endif /* @@ -73,12 +72,11 @@ static struct seeprom_cmd { unsigned char bits[3]; } seeprom_read = {3, {1, 1, 0}}; - /* * Wait for the SEERDY to go high; about 800 ns. */ -#define CLOCK_PULSE(p, rdy) \ - while ((inb(p) & rdy) == 0) { \ +#define CLOCK_PULSE(sd, rdy) \ + while ((SEEPROM_INB(sd) & rdy) == 0) { \ ; /* Do nothing */ \ } @@ -86,56 +84,56 @@ static struct seeprom_cmd { * Read the serial EEPROM and returns 1 if successful and 0 if * not successful. */ -int read_seeprom (u_long offset, - u_short *buf, - u_int start_addr, - int count, - u_short CS, /* chip select */ - u_short CK, /* clock */ - u_short DO, /* data out */ - u_short DI, /* data in */ - u_short RDY, /* ready */ - u_short MS /* mode select */) +int +read_seeprom(sd, buf, start_addr, count) + struct seeprom_descriptor *sd; + u_int16_t *buf; +#if defined(__FreeBSD__) + u_int start_addr; + int count; +#elif defined(__NetBSD__) + bus_io_size_t start_addr; + bus_io_size_t count; +#endif { int i = 0, k = 0; - unsigned char temp; + u_int16_t v; + u_int8_t temp; /* * Read the requested registers of the seeprom. The loop * will range from 0 to count-1. */ - for (k = start_addr; k < count + start_addr; k = k + 1) { + for (k = start_addr; k < count + start_addr; k++) { /* Send chip select for one clock cycle. */ - outb(offset, MS | CK | CS); - CLOCK_PULSE(offset, RDY); + temp = sd->sd_MS ^ sd->sd_CS; + SEEPROM_OUTB(sd, temp ^ sd->sd_CK); + CLOCK_PULSE(sd, sd->sd_RDY); /* * Now we're ready to send the read command followed by the * address of the 16-bit register we want to read. */ - for (i = 0; i < seeprom_read.len; i = i + 1) { - if (seeprom_read.bits[i]) - temp = MS | CS | DO; - else - temp = MS | CS; - outb(offset, temp); - CLOCK_PULSE(offset, RDY); - temp = temp ^ CK; - outb(offset, temp); - CLOCK_PULSE(offset, RDY); + for (i = 0; i < seeprom_read.len; i++) { + if (seeprom_read.bits[i] != 0) + temp ^= sd->sd_DO; + SEEPROM_OUTB(sd, temp); + CLOCK_PULSE(sd, sd->sd_RDY); + SEEPROM_OUTB(sd, temp ^ sd->sd_CK); + CLOCK_PULSE(sd, sd->sd_RDY); + if (seeprom_read.bits[i] != 0) + temp ^= sd->sd_DO; } /* Send the 6 bit address (MSB first, LSB last). */ - for (i = 5; i >= 0; i = i - 1) { - /* k is the address, i is the bit */ - if (k & (1 << i)) - temp = MS | CS | DO; - else - temp = MS | CS; - outb(offset, temp); - CLOCK_PULSE(offset, RDY); - temp = temp ^ CK; - outb(offset, temp); - CLOCK_PULSE(offset, RDY); + for (i = 5; i >= 0; i--) { + if ((k & (1 << i)) != 0) + temp ^= sd->sd_DO; + SEEPROM_OUTB(sd, temp); + CLOCK_PULSE(sd, sd->sd_RDY); + SEEPROM_OUTB(sd, temp ^ sd->sd_CK); + CLOCK_PULSE(sd, sd->sd_RDY); + if ((k & (1 << i)) != 0) + temp ^= sd->sd_DO; } /* @@ -144,27 +142,27 @@ int read_seeprom (u_long offset, * with bit 0 (LSB). The initial 0 will be shifted off the * top of our word as we let the loop run from 0 to 16. */ - for (i = 0; i <= 16; i = i + 1) { - temp = MS | CS; - outb(offset, temp); - CLOCK_PULSE(offset, RDY); - temp = temp ^ CK; - if (inb(offset) & DI) - buf[k - start_addr] = - (buf[k - start_addr] << 1) | 0x1; - else - buf[k - start_addr] = (buf[k - start_addr]<< 1); - outb(offset, temp); - CLOCK_PULSE(offset, RDY); + v = 0; + for (i = 16; i >= 0; i--) { + SEEPROM_OUTB(sd, temp); + CLOCK_PULSE(sd, sd->sd_RDY); + v <<= 1; + if (SEEPROM_INB(sd) & sd->sd_DI) + v |= 1; + SEEPROM_OUTB(sd, temp ^ sd->sd_CK); + CLOCK_PULSE(sd, sd->sd_RDY); } + buf[k - start_addr] = v; + /* Reset the chip select for the next command cycle. */ - outb(offset, MS); - CLOCK_PULSE(offset, RDY); - outb(offset, MS | CK); - CLOCK_PULSE(offset, RDY); - outb(offset, MS); - CLOCK_PULSE(offset, RDY); + temp = sd->sd_MS; + SEEPROM_OUTB(sd, temp); + CLOCK_PULSE(sd, sd->sd_RDY); + SEEPROM_OUTB(sd, temp ^ sd->sd_CK); + CLOCK_PULSE(sd, sd->sd_RDY); + SEEPROM_OUTB(sd, temp); + CLOCK_PULSE(sd, sd->sd_RDY); } #if 0 printf ("Serial EEPROM:"); diff --git a/sys/dev/ic/93cx6.h b/sys/dev/ic/93cx6.h index 18030d65c50..8a2015b114e 100644 --- a/sys/dev/ic/93cx6.h +++ b/sys/dev/ic/93cx6.h @@ -20,7 +20,7 @@ * 4. Modifications may be freely made to this file if the above conditions * are met. * - * $Id: 93cx6.h,v 1.1 1996/05/05 12:42:28 deraadt Exp $ + * $Id: 93cx6.h,v 1.2 1996/06/27 21:15:47 shawn Exp $ */ #include <sys/param.h> @@ -28,6 +28,22 @@ #include <sys/systm.h> #endif +struct seeprom_descriptor { +#if defined(__FreeBSD__) + u_long sd_iobase; +#elif defined(__NetBSD__) + bus_chipset_tag_t sd_bc; + bus_io_handle_t sd_ioh; + bus_io_size_t sd_offset; +#endif + u_int16_t sd_MS; + u_int16_t sd_RDY; + u_int16_t sd_CS; + u_int16_t sd_CK; + u_int16_t sd_DO; + u_int16_t sd_DI; +}; + /* * This function will read count 16-bit words from the serial EEPROM and * return their value in buf. The port address of the aic7xxx serial EEPROM @@ -43,13 +59,21 @@ * * A failed read attempt returns 0, and a successful read returns 1. */ -int read_seeprom (u_long offset, - u_short *buf, - u_int start_addr, - int count, - u_short CS, - u_short CK, - u_short DO, - u_short DI, - u_short RDY, - u_short MS); + +#if defined(__FreeBSD__) +#define SEEPROM_INB(sd) inb(sd->sd_iobase) +#define SEEPROM_OUTB(sd, value) outb(sd->sd_iobase, value) +#elif defined(__NetBSD__) +#define SEEPROM_INB(sd) \ + bus_io_read_1(sd->sd_bc, sd->sd_ioh, sd->sd_offset) +#define SEEPROM_OUTB(sd, value) \ + bus_io_write_1(sd->sd_bc, sd->sd_ioh, sd->sd_offset, value) +#endif + +#if defined(__FreeBSD__) +int read_seeprom __P((struct seeprom_descriptor *sd, + u_int16_t *buf, u_int start_addr, int count)); +#elif defined(__NetBSD__) +int read_seeprom __P((struct seeprom_descriptor *sd, + u_int16_t *buf, bus_io_size_t start_addr, bus_io_size_t count)); +#endif diff --git a/sys/dev/ic/aic7xxx.c b/sys/dev/ic/aic7xxx.c index 614cd0616df..40deee1acc4 100644 --- a/sys/dev/ic/aic7xxx.c +++ b/sys/dev/ic/aic7xxx.c @@ -1,10 +1,8 @@ -/* $NetBSD: aic7xxx.c,v 1.8 1996/05/20 00:58:07 thorpej Exp $ */ - /* * Generic driver for the aic7xxx based adaptec SCSI controllers * Product specific probe and attach routines can be found in: * i386/eisa/aic7770.c 27/284X and aic7770 motherboard controllers - * pci/aic7870.c 3940, 2940, aic7870 and aic7850 controllers + * pci/aic7870.c 3940, 2940, aic7880, aic7870 and aic7850 controllers * * Copyright (c) 1994, 1995, 1996 Justin T. Gibbs. * All rights reserved. @@ -32,6 +30,8 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. + * + * $Id: aic7xxx.c,v 1.7 1996/06/27 21:15:47 shawn Exp $ */ /* * TODO: @@ -158,8 +158,6 @@ #endif #endif /* defined(__NetBSD__) */ -#define PAGESIZ NBPG - #include <sys/kernel.h> #define KVTOPHYS(x) vtophys(x) @@ -171,7 +169,7 @@ u_long ahc_unit = 0; #endif #ifdef AHC_DEBUG -static int ahc_debug = AHC_SHOWSENSE; +static int ahc_debug = AHC_DEBUG; #endif #ifdef AHC_BROKEN_CACHE @@ -239,8 +237,8 @@ static struct scsi_device ahc_dev = #define RESTART_SEQUENCER(ahc) \ do { \ AHC_OUTB(ahc, SEQCTL, SEQRESET|FASTMODE); \ - } while (AHC_INB(ahc, SEQADDR0) != 0 && \ - AHC_INB(ahc, SEQADDR1) != 0); \ + } while((AHC_INB(ahc, SEQADDR0) != 0) \ + || (AHC_INB(ahc, SEQADDR1) != 0)); \ \ UNPAUSE_SEQUENCER(ahc); @@ -288,7 +286,8 @@ static int ahc_reset_device __P((struct ahc_data *ahc, int target, static void ahc_reset_current_bus __P((struct ahc_data *ahc)); static void ahc_run_done_queue __P((struct ahc_data *ahc)); static void ahc_scsirate __P((struct ahc_data* ahc, u_char *scsirate, - int period, int offset, int target)); + int period, int offset, char channel, + int target)); #if defined(__FreeBSD__) static timeout_t ahc_timeout; @@ -366,11 +365,6 @@ static struct { { 0x100, 50, "20.0" }, { 0x110, 62, "16.0" }, { 0x120, 75, "13.4" }, - { 0x130, 175, "5.7" }, - { 0x140, 200, "5.0" }, - { 0x150, 225, "4.4" }, - { 0x160, 250, "4.0" }, - { 0x170, 275, "3.6" }, { 0x000, 100, "10.0" }, { 0x010, 125, "8.0" }, { 0x020, 150, "6.67" }, @@ -424,12 +418,14 @@ ahc_construct(ahc, bc, ioh, type, flags) } bzero(ahc, sizeof(struct ahc_data)); #endif - SIMPLEQ_INIT(&ahc->free_scbs); - SIMPLEQ_INIT(&ahc->page_scbs); - SIMPLEQ_INIT(&ahc->waiting_scbs); - SIMPLEQ_INIT(&ahc->assigned_scbs); + STAILQ_INIT(&ahc->free_scbs); + STAILQ_INIT(&ahc->page_scbs); + STAILQ_INIT(&ahc->waiting_scbs); + STAILQ_INIT(&ahc->assigned_scbs); #if defined(__FreeBSD__) ahc->unit = unit; +#endif +#if defined(__FreeBSD__) ahc->baseport = iobase; #elif defined(__NetBSD__) ahc->sc_bc = bc; @@ -509,39 +505,59 @@ ahc_reset(devname, bc, ioh) * Look up the valid period to SCSIRATE conversion in our table. */ static void -ahc_scsirate(ahc, scsirate, period, offset, target ) +ahc_scsirate(ahc, scsirate, period, offset, channel, target ) struct ahc_data *ahc; u_char *scsirate; short period; u_char offset; + char channel; int target; { int i; for (i = 0; i < ahc_num_syncrates; i++) { + u_char ultra_enb; + u_char sxfrctl0; + u_long ultra_enb_addr; if ((ahc_syncrates[i].period - period) >= 0) { /* * Watch out for Ultra speeds when ultra is not * enabled and vice-versa. */ - if (ahc->type & AHC_ULTRA) { - if (!(ahc_syncrates[i].sxfr & ULTRA_SXFR)) - break; /* Use Async */ + if(!(ahc->type & AHC_ULTRA) + && (ahc_syncrates[i].sxfr & ULTRA_SXFR)) { + /* + * This should only happen if the + * drive is the first to negotiate + * and chooses a high rate. We'll + * just move down the table util + * we hit a non ultra speed. + */ + continue; + } + *scsirate = (ahc_syncrates[i].sxfr) | (offset & 0x0f); + + /* + * Ensure Ultra mode is set properly for + * this target. + */ + ultra_enb_addr = ULTRA_ENB; + if(channel == 'B' || target > 7) + ultra_enb_addr++; + ultra_enb = AHC_INB(ahc, ultra_enb_addr); + sxfrctl0 = AHC_INB(ahc, SXFRCTL0); + if (ahc_syncrates[i].sxfr & ULTRA_SXFR) { + ultra_enb |= 0x01 << (target & 0x07); + sxfrctl0 |= ULTRAEN; } else { - if (ahc_syncrates[i].sxfr & ULTRA_SXFR) { - /* - * This should only happen if the - * drive is the first to negotiate - * and chooses a high rate. We'll - * just move down the table util - * we hit a non ultra speed. - */ - continue; - } + ultra_enb &= ~(0x01 << (target & 0x07)); + sxfrctl0 &= ~ULTRAEN; } - *scsirate = (ahc_syncrates[i].sxfr) | (offset & 0x0f); + AHC_OUTB(ahc, ultra_enb_addr, ultra_enb); + AHC_OUTB(ahc, SXFRCTL0, sxfrctl0); + if(bootverbose) { printf("%s: target %d synchronous at %sMHz," " offset = 0x%x\n", @@ -760,7 +776,7 @@ ahc_run_waiting_queues(ahc) struct scb* scb; u_char cur_scb; - if(!(ahc->assigned_scbs.sqh_first || ahc->waiting_scbs.sqh_first)) + if(!(ahc->assigned_scbs.stqh_first || ahc->waiting_scbs.stqh_first)) return; PAUSE_SEQUENCER(ahc); @@ -770,13 +786,13 @@ ahc_run_waiting_queues(ahc) * First handle SCBs that are waiting but have been * assigned a slot. */ - while((scb = ahc->assigned_scbs.sqh_first) != NULL) { - SIMPLEQ_REMOVE_HEAD(&ahc->assigned_scbs, scb, links); + while((scb = ahc->assigned_scbs.stqh_first) != NULL) { + STAILQ_REMOVE_HEAD(&ahc->assigned_scbs, links); AHC_OUTB(ahc, SCBPTR, scb->position); ahc_send_scb(ahc, scb); /* Mark this as an active command */ - scb->flags = SCB_ACTIVE; + scb->flags ^= SCB_ASSIGNEDQ|SCB_ACTIVE; AHC_OUTB(ahc, QINFIFO, scb->position); if (!(scb->xs->flags & SCSI_NOMASK)) { @@ -786,7 +802,7 @@ ahc_run_waiting_queues(ahc) SC_DEBUG(scb->xs->sc_link, SDEV_DB3, ("cmd_sent\n")); } /* Now deal with SCBs that require paging */ - if((scb = ahc->waiting_scbs.sqh_first) != NULL) { + if((scb = ahc->waiting_scbs.stqh_first) != NULL) { u_char disc_scb = AHC_INB(ahc, DISCONNECTED_SCBH); u_char active = AHC_INB(ahc, FLAGS) & (SELECTED|IDENTIFY_SEEN); int count = 0; @@ -799,8 +815,7 @@ ahc_run_waiting_queues(ahc) break; /* - * Advance disc_scb to the next on in the - * list. + * Check the next SCB on in the list. */ AHC_OUTB(ahc, SCBPTR, disc_scb); next_scb = AHC_INB(ahc, SCB_NEXT); @@ -823,8 +838,7 @@ ahc_run_waiting_queues(ahc) u_char out_scbi; struct scb* out_scbp; - SIMPLEQ_REMOVE_HEAD(&ahc->waiting_scbs, scb, - links); + STAILQ_REMOVE_HEAD(&ahc->waiting_scbs, links); /* * Find the in-core SCB for the one @@ -837,7 +851,7 @@ ahc_run_waiting_queues(ahc) ahc_page_scb(ahc, out_scbp, scb); /* Mark this as an active command */ - scb->flags = SCB_ACTIVE; + scb->flags ^= SCB_WAITINGQ|SCB_ACTIVE; /* Queue the command */ AHC_OUTB(ahc, QINFIFO, scb->position); @@ -854,7 +868,7 @@ ahc_run_waiting_queues(ahc) } else break; - } while((scb = ahc->waiting_scbs.sqh_first) != NULL); + } while((scb = ahc->waiting_scbs.stqh_first) != NULL); if(count) { /* @@ -906,11 +920,11 @@ ahc_intr(arg) { int intstat; u_char status; - struct scb *scb = NULL; - struct scsi_xfer *xs = NULL; - struct ahc_data *ahc = (struct ahc_data *)arg; + struct scb *scb; + struct scsi_xfer *xs; + struct ahc_data *ahc = (struct ahc_data *)arg; - intstat = AHC_INB(ahc, INTSTAT); + intstat = AHC_INB(ahc, INTSTAT); /* * Is this interrupt for me? or for * someone who is sharing my interrupt @@ -936,11 +950,6 @@ ahc_intr(arg) AHC_INB(ahc, SEQADDR0)); } if (intstat & SEQINT) { - /* - * This code isn't used by the SCB page-in code. It - * should probably be moved to cut out the extra - * inb. - */ u_short targ_mask; u_char target = (AHC_INB(ahc, SCSIID) >> 4) & 0x0f; u_char scratch_offset = target; @@ -952,39 +961,6 @@ ahc_intr(arg) targ_mask = (0x01 << scratch_offset); switch (intstat & SEQINT_MASK) { - case BAD_PHASE: - panic("%s:%c:%d: unknown scsi bus phase. " - "Attempting to continue\n", - ahc_name(ahc), channel, target); - break; - case SEND_REJECT: - { - u_char rejbyte = AHC_INB(ahc, REJBYTE); - if(( rejbyte & 0xf0) == 0x20) { - /* Tagged Message */ - printf("\n%s:%c:%d: Tagged message " - "received without identify. " - "Disabling tagged commands " - "for this target.\n", - ahc_name(ahc), - channel, target); - ahc->tagenable &= ~targ_mask; - } - else - printf("%s:%c:%d: Warning - " - "unknown message recieved from " - "target (0x%x - 0x%x). Rejecting\n", - ahc_name(ahc), channel, target, - rejbyte, - AHC_INB(ahc, REJBYTE_EXT)); - break; - } - case NO_IDENT: - panic("%s:%c:%d: Target did not send an IDENTIFY " - "message. SAVED_TCL == 0x%x\n", - ahc_name(ahc), channel, target, - AHC_INB(ahc, SAVED_TCL)); - break; case NO_MATCH: if(ahc->flags & AHC_PAGESCBS) { /* SCB Page-in request */ @@ -993,6 +969,18 @@ ahc_intr(arg) u_char disc_scb; struct scb *outscb; u_char arg_1 = AHC_INB(ahc, ARG_1); + + /* + * We should succeed, so set this now. + * If we don't, and one of the methods + * we use to aquire an SCB calls ahc_done, + * we may wind up in our start routine + * and unpause the adapter without giving + * it the correct return value, which will + * cause a hang. + */ + AHC_OUTB(ahc, RETURN_1, SCB_PAGEDIN); + if(arg_1 == SCB_LIST_NULL) { /* Non-tagged command */ int index = target | @@ -1002,6 +990,10 @@ ahc_intr(arg) else scb = ahc->scbarray[arg_1]; + if(!(scb->flags & SCB_PAGED_OUT)) + panic("%s: Request to page in a" + "non paged out SCB.", + ahc_name(ahc)); /* * Now to pick the SCB to page out. * Either take a free SCB, an assigned SCB, @@ -1009,26 +1001,29 @@ ahc_intr(arg) * one on the disconnected SCB list, or * as a last resort a queued SCB. */ - if((outscb = ahc->free_scbs.sqh_first) != NULL) { - SIMPLEQ_REMOVE_HEAD(&ahc->free_scbs, - outscb, links); + if(ahc->free_scbs.stqh_first) { + outscb = ahc->free_scbs.stqh_first; + STAILQ_REMOVE_HEAD(&ahc->free_scbs, + links); scb->position = outscb->position; outscb->position = SCB_LIST_NULL; - SIMPLEQ_INSERT_HEAD(&ahc->page_scbs, - outscb, links); + STAILQ_INSERT_HEAD(&ahc->page_scbs, + outscb, links); AHC_OUTB(ahc, SCBPTR, scb->position); ahc_send_scb(ahc, scb); scb->flags &= ~SCB_PAGED_OUT; goto pagein_done; } - if((outscb = ahc->assigned_scbs.sqh_first) != NULL) { - SIMPLEQ_REMOVE_HEAD(&ahc->assigned_scbs, - outscb, links); + if(ahc->assigned_scbs.stqh_first) { + outscb = ahc->assigned_scbs.stqh_first; + STAILQ_REMOVE_HEAD(&ahc->assigned_scbs, + links); + outscb->flags ^= SCB_ASSIGNEDQ + |SCB_WAITINGQ; scb->position = outscb->position; outscb->position = SCB_LIST_NULL; - SIMPLEQ_INSERT_HEAD(&ahc->waiting_scbs, - outscb, links); - outscb->flags = SCB_WAITINGQ; + STAILQ_INSERT_HEAD(&ahc->waiting_scbs, + outscb, links); AHC_OUTB(ahc, SCBPTR, scb->position); ahc_send_scb(ahc, scb); scb->flags &= ~SCB_PAGED_OUT; @@ -1037,7 +1032,6 @@ ahc_intr(arg) if(intstat & CMDCMPLT) { int scb_index; - printf("PIC\n"); AHC_OUTB(ahc, CLRINT, CLRCMDINT); scb_index = AHC_INB(ahc, QOUTFIFO); if(!(AHC_INB(ahc, QOUTCNT) & ahc->qcntmask)) @@ -1091,8 +1085,8 @@ ahc_intr(arg) * end of the queue instead. */ int i; - int saved_queue[AHC_SCB_MAX]; - int queued = AHC_INB(ahc, QINCNT) & ahc->qcntmask; + u_char saved_queue[AHC_SCB_MAX]; + u_char queued = AHC_INB(ahc, QINCNT) & ahc->qcntmask; /* Count the command we removed already */ saved_queue[0] = disc_scb; @@ -1114,16 +1108,17 @@ ahc_intr(arg) untimeout(ahc_timeout, (caddr_t)outscb); scb->position = outscb->position; outscb->position = SCB_LIST_NULL; - SIMPLEQ_INSERT_HEAD(&ahc->waiting_scbs, + STAILQ_INSERT_HEAD(&ahc->waiting_scbs, outscb, links); - outscb->flags = SCB_WAITINGQ; + outscb->flags |= SCB_WAITINGQ; ahc_send_scb(ahc, scb); scb->flags &= ~SCB_PAGED_OUT; } - else + else { panic("Page-in request with no candidates"); + AHC_OUTB(ahc, RETURN_1, 0); + } pagein_done: - AHC_OUTB(ahc, RETURN_1, SCB_PAGEDIN); } else { printf("%s:%c:%d: no active SCB for " @@ -1138,6 +1133,39 @@ pagein_done: AHC_OUTB(ahc, RETURN_1, 0); } break; + case SEND_REJECT: + { + u_char rejbyte = AHC_INB(ahc, REJBYTE); + if(( rejbyte & 0xf0) == 0x20) { + /* Tagged Message */ + printf("\n%s:%c:%d: Tagged message " + "received without identify. " + "Disabling tagged commands " + "for this target.\n", + ahc_name(ahc), + channel, target); + ahc->tagenable &= ~targ_mask; + } + else + printf("%s:%c:%d: Warning - " + "unknown message recieved from " + "target (0x%x - 0x%x). Rejecting\n", + ahc_name(ahc), channel, target, + rejbyte, + AHC_INB(ahc, REJBYTE_EXT)); + break; + } + case NO_IDENT: + panic("%s:%c:%d: Target did not send an IDENTIFY " + "message. SAVED_TCL == 0x%x\n", + ahc_name(ahc), channel, target, + AHC_INB(ahc, SAVED_TCL)); + break; + case BAD_PHASE: + printf("%s:%c:%d: unknown scsi bus phase. " + "Attempting to continue\n", + ahc_name(ahc), channel, target); + break; case SDTR_MSG: { short period; @@ -1159,9 +1187,9 @@ pagein_done: maxoffset = 0x08; else maxoffset = 0x0f; - ahc_scsirate(ahc, &rate, period, - MIN(offset,maxoffset), - target); + ahc_scsirate(ahc, &rate, period, + MIN(offset, maxoffset), + channel, target); /* Preserve the WideXfer flag */ targ_scratch = rate | (targ_scratch & WIDEXFER); AHC_OUTB(ahc, TARG_SCRATCH + scratch_offset, @@ -1471,25 +1499,18 @@ pagein_done: sc_print_addr(xs->sc_link); printf("Target Busy\n"); break; -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ case SCSI_QUEUE_FULL: /* - * The upper level SCSI code will eventually + * The upper level SCSI code will someday * handle this properly. */ sc_print_addr(xs->sc_link); printf("Queue Full\n"); - scb->flags = SCB_ASSIGNEDQ; - SIMPLEQ_INSERT_TAIL(&ahc->assigned_scbs, + scb->flags |= SCB_ASSIGNEDQ; + STAILQ_INSERT_TAIL(&ahc->assigned_scbs, scb, links); break; -#elif defined(__NetBSD__) - /* - * XXX - - * Do we need to handle this ? - * But FreeBSD MI SCSI code seems to - * do nothing about this. - */ #endif default: sc_print_addr(xs->sc_link); @@ -1630,6 +1651,31 @@ pagein_done: "unknown operation."); break; } + case DATA_OVERRUN: + { + /* + * When the sequencer detects an overrun, it + * sets STCNT to 0x00ffffff and allows the + * target to complete its transfer in + * BITBUCKET mode. + */ + u_char scbindex = AHC_INB(ahc, SCB_TAG); + u_int32_t overrun; + scb = ahc->scbarray[scbindex]; + overrun = AHC_INB(ahc, STCNT0) + | (AHC_INB(ahc, STCNT1) << 8) + | (AHC_INB(ahc, STCNT2) << 16); + overrun = 0x00ffffff - overrun; + sc_print_addr(scb->xs->sc_link); + printf("data overrun of %d bytes detected." + " Forcing a retry.\n", overrun); + /* + * Set this and it will take affect when the + * target does a command complete. + */ + scb->xs->error = XS_DRIVER_STUFFUP; + break; + } #if NOT_YET /* XXX Fill these in later */ case MESG_BUFFER_BUSY: @@ -1663,10 +1709,7 @@ clear: int scb_index = AHC_INB(ahc, SCB_TAG); status = AHC_INB(ahc, SSTAT1); - scb = ahc->scbarray[scb_index]; - if (scb != NULL) /* XXX - is this case exist ? */ - xs = scb->xs; if (status & SCSIRSTI) { char channel; @@ -1699,6 +1742,7 @@ clear: u_char mesg_out = MSG_NOP; u_char lastphase = AHC_INB(ahc, LASTPHASE); + xs = scb->xs; sc_print_addr(xs->sc_link); switch(lastphase) { @@ -1730,10 +1774,10 @@ clear: printf("parity error during %s phase.\n", phase); /* - * We've set the hardware to assert ATN if we - * get a parity error on "in" phases, so all we + * We've set the hardware to assert ATN if we + * get a parity error on "in" phases, so all we * need to do is stuff the message buffer with - * the appropriate message. In phases have set + * the appropriate message. "In" phases have set * mesg_out to something other than MSG_NOP. */ if(mesg_out != MSG_NOP) { @@ -1750,7 +1794,9 @@ clear: else if (status & SELTO) { u_char waiting; u_char flags; - xs->error = XS_SELTIMEOUT; + + xs = scb->xs; + xs->error = XS_SELTIMEOUT; /* * Clear any pending messages for the timed out * target, and mark the target as free @@ -1764,6 +1810,8 @@ clear: IS_SCSIBUS_B(ahc, xs->sc_link) #endif ? 'B' : 'A'); + /* Stop the selection */ + AHC_OUTB(ahc, SCSISEQ, 0); AHC_OUTB(ahc, SCB_CONTROL, 0); @@ -1780,7 +1828,7 @@ clear: RESTART_SEQUENCER(ahc); } else if (!(status & BUSFREE)) { - sc_print_addr(xs->sc_link); + sc_print_addr(scb->xs->sc_link); printf("Unknown SCSIINT. Status = 0x%x\n", status); AHC_OUTB(ahc, CLRSINT1, status); UNPAUSE_SEQUENCER(ahc); @@ -1909,6 +1957,7 @@ ahc_init(ahc) struct ahc_data *ahc; { u_char scsi_conf, sblkctl, i; + u_short ultraenable = 0; int max_targ = 15; /* * Assume we have a board at this stage and it has been reset. @@ -2115,6 +2164,22 @@ ahc_init(ahc) */ target_settings &= 0x7f; } + if(ahc->type & AHC_ULTRA) { + /* + * Enable Ultra for any target that + * has a valid ultra syncrate setting. + */ + u_char rate = target_settings & 0x70; + if(rate == 0x00 || rate == 0x10 || + rate == 0x20 || rate == 0x40) { + if(rate == 0x40) { + /* Treat 10MHz specially */ + target_settings &= ~0x70; + } + else + ultraenable |= (0x01 << i); + } + } } AHC_OUTB(ahc, TARG_SCRATCH+i,target_settings); } @@ -2133,6 +2198,9 @@ ahc_init(ahc) ahc->tagenable = 0; ahc->orderedtag = 0; + AHC_OUTB(ahc, ULTRA_ENB, ultraenable & 0xff); + AHC_OUTB(ahc, ULTRA_ENB + 1, (ultraenable >> 8) & 0xff); + #ifdef AHC_DEBUG /* How did we do? */ if(ahc_debug & AHC_SHOWMISC) @@ -2206,8 +2274,8 @@ ahcminphys(bp) * discontinuous physically, hense the "page per segment" limit * enforced here. */ - if (bp->b_bcount > ((AHC_NSEG - 1) * PAGESIZ)) { - bp->b_bcount = ((AHC_NSEG - 1) * PAGESIZ); + if (bp->b_bcount > ((AHC_NSEG - 1) * PAGE_SIZE)) { + bp->b_bcount = ((AHC_NSEG - 1) * PAGE_SIZE); } #if defined(__NetBSD__) minphys(bp); @@ -2223,49 +2291,49 @@ static int32_t ahc_scsi_cmd(xs) struct scsi_xfer *xs; { - struct scb *scb; - struct ahc_dma_seg *sg; - int seg; /* scatter gather seg being worked on */ - int thiskv; - physaddr thisphys, nextphys; - int bytes_this_seg, bytes_this_page, datalen, flags; - struct ahc_data *ahc; + struct scb *scb; + struct ahc_dma_seg *sg; + int seg; /* scatter gather seg being worked on */ + int thiskv; + physaddr thisphys, nextphys; + int bytes_this_seg, bytes_this_page, datalen, flags; + struct ahc_data *ahc; u_short mask; - int s; + int s; ahc = (struct ahc_data *)xs->sc_link->adapter_softc; - mask = (0x01 << (xs->sc_link->target + mask = (0x01 << (xs->sc_link->target #if defined(__FreeBSD__) | ((u_long)xs->sc_link->fordriver & 0x08))); #elif defined(__NetBSD__) | (IS_SCSIBUS_B(ahc, xs->sc_link) ? SELBUSB : 0) )); #endif - SC_DEBUG(xs->sc_link, SDEV_DB2, ("ahc_scsi_cmd\n")); - /* - * get an scb to use. If the transfer - * is from a buf (possibly from interrupt time) - * then we can't allow it to sleep - */ - flags = xs->flags; - if (flags & ITSDONE) { - printf("%s: Already done?", ahc_name(ahc)); - xs->flags &= ~ITSDONE; - } - if (!(flags & INUSE)) { - printf("%s: Not in use?", ahc_name(ahc)); - xs->flags |= INUSE; - } - if (!(scb = ahc_get_scb(ahc, flags))) { - xs->error = XS_DRIVER_STUFFUP; - return (TRY_AGAIN_LATER); - } - SC_DEBUG(xs->sc_link, SDEV_DB3, ("start scb(%p)\n", scb)); - scb->xs = xs; - if (flags & SCSI_RESET) + SC_DEBUG(xs->sc_link, SDEV_DB2, ("ahc_scsi_cmd\n")); + /* + * get an scb to use. If the transfer + * is from a buf (possibly from interrupt time) + * then we can't allow it to sleep + */ + flags = xs->flags; + if (flags & ITSDONE) { + printf("%s: Already done?", ahc_name(ahc)); + xs->flags &= ~ITSDONE; + } + if (!(flags & INUSE)) { + printf("%s: Not in use?", ahc_name(ahc)); + xs->flags |= INUSE; + } + if (!(scb = ahc_get_scb(ahc, flags))) { + xs->error = XS_DRIVER_STUFFUP; + return (TRY_AGAIN_LATER); + } + SC_DEBUG(xs->sc_link, SDEV_DB3, ("start scb(%p)\n", scb)); + scb->xs = xs; + if (flags & SCSI_RESET) scb->flags |= SCB_DEVICE_RESET|SCB_IMMED; - /* - * Put all the arguments for the xfer in the scb - */ + /* + * Put all the arguments for the xfer in the scb + */ if(ahc->tagenable & mask) { scb->control |= TAG_ENB; @@ -2328,8 +2396,8 @@ ahc_scsi_cmd(xs) * length */ /* how far to the end of the page */ - nextphys = (thisphys & (~(PAGESIZ - 1))) - + PAGESIZ; + nextphys = (thisphys & (~(PAGE_SIZE- 1))) + + PAGE_SIZE; bytes_this_page = nextphys - thisphys; /**** or the data ****/ bytes_this_page = min(bytes_this_page ,datalen); @@ -2337,8 +2405,8 @@ ahc_scsi_cmd(xs) datalen -= bytes_this_page; /* get more ready for the next page */ - thiskv = (thiskv & (~(PAGESIZ - 1))) - + PAGESIZ; + thiskv = (thiskv & (~(PAGE_SIZE - 1))) + + PAGE_SIZE; if (datalen) thisphys = KVTOPHYS(thiskv); } @@ -2398,7 +2466,7 @@ ahc_scsi_cmd(xs) AHC_OUTB(ahc, SCBPTR, curscb); AHC_OUTB(ahc, QINFIFO, scb->position); UNPAUSE_SEQUENCER(ahc); - scb->flags = SCB_ACTIVE; + scb->flags |= SCB_ACTIVE; if (!(flags & SCSI_NOMASK)) { timeout(ahc_timeout, (caddr_t)scb, (xs->timeout * hz) / 1000); @@ -2406,8 +2474,8 @@ ahc_scsi_cmd(xs) SC_DEBUG(xs->sc_link, SDEV_DB3, ("cmd_sent\n")); } else { - scb->flags = SCB_WAITINGQ; - SIMPLEQ_INSERT_TAIL(&ahc->waiting_scbs, scb, links); + scb->flags |= SCB_WAITINGQ; + STAILQ_INSERT_TAIL(&ahc->waiting_scbs, scb, links); ahc_run_waiting_queues(ahc); } if (!(flags & SCSI_NOMASK)) { @@ -2446,10 +2514,14 @@ ahc_free_scb(ahc, scb, flags) opri = splbio(); + /* Clean up for the next user */ scb->flags = SCB_FREE; + scb->control = 0; + scb->status = 0; + if(scb->position == SCB_LIST_NULL) { - SIMPLEQ_INSERT_HEAD(&ahc->page_scbs, scb, links); - if(!scb->links.sqe_next && !ahc->free_scbs.sqh_first) + STAILQ_INSERT_HEAD(&ahc->page_scbs, scb, links); + if(!scb->links.stqe_next && !ahc->free_scbs.stqh_first) /* * If there were no SCBs availible, wake anybody waiting * for one to come free. @@ -2463,11 +2535,11 @@ ahc_free_scb(ahc, scb, flags) * completes for a particular interrupt are completed * or when we start another command. */ - else if((wscb = ahc->waiting_scbs.sqh_first) != NULL) { - SIMPLEQ_REMOVE_HEAD(&ahc->waiting_scbs, wscb, links); + else if((wscb = ahc->waiting_scbs.stqh_first) != NULL) { + STAILQ_REMOVE_HEAD(&ahc->waiting_scbs, links); wscb->position = scb->position; - SIMPLEQ_INSERT_HEAD(&ahc->assigned_scbs, wscb, links); - wscb->flags = SCB_ASSIGNEDQ; + STAILQ_INSERT_HEAD(&ahc->assigned_scbs, wscb, links); + wscb->flags ^= SCB_WAITINGQ|SCB_ASSIGNEDQ; /* * The "freed" SCB will need to be assigned a slot @@ -2475,8 +2547,8 @@ ahc_free_scb(ahc, scb, flags) * queue. */ scb->position = SCB_LIST_NULL; - SIMPLEQ_INSERT_HEAD(&ahc->page_scbs, scb, links); - if(!scb->links.sqe_next && !ahc->free_scbs.sqh_first) + STAILQ_INSERT_HEAD(&ahc->page_scbs, scb, links); + if(!scb->links.stqe_next && !ahc->free_scbs.stqh_first) /* * If there were no SCBs availible, wake anybody waiting * for one to come free. @@ -2484,17 +2556,17 @@ ahc_free_scb(ahc, scb, flags) wakeup((caddr_t)&ahc->free_scbs); } else { - SIMPLEQ_INSERT_HEAD(&ahc->free_scbs, scb, links); -#ifdef AHC_DEBUG - ahc->activescbs--; -#endif - if(!scb->links.sqe_next && !ahc->page_scbs.sqh_first) + STAILQ_INSERT_HEAD(&ahc->free_scbs, scb, links); + if(!scb->links.stqe_next && !ahc->page_scbs.stqh_first) /* * If there were no SCBs availible, wake anybody waiting * for one to come free. */ wakeup((caddr_t)&ahc->free_scbs); } +#ifdef AHC_DEBUG + ahc->activescbs--; +#endif splx(opri); } @@ -2518,13 +2590,13 @@ ahc_get_scb(ahc, flags) * but only if we can't allocate a new one. */ while (1) { - if((scbp = ahc->free_scbs.sqh_first)) { - SIMPLEQ_REMOVE_HEAD(&ahc->free_scbs, scbp, links); + if((scbp = ahc->free_scbs.stqh_first)) { + STAILQ_REMOVE_HEAD(&ahc->free_scbs, links); } - else if((scbp = ahc->page_scbs.sqh_first)) { - SIMPLEQ_REMOVE_HEAD(&ahc->page_scbs, scbp, links); + else if((scbp = ahc->page_scbs.stqh_first)) { + STAILQ_REMOVE_HEAD(&ahc->page_scbs, links); } - else if (ahc->numscbs < ahc->maxscbs) { + else if(ahc->numscbs < ahc->maxscbs) { scbp = (struct scb *) malloc(sizeof(struct scb), M_TEMP, M_NOWAIT); if (scbp) { @@ -2556,17 +2628,14 @@ ahc_get_scb(ahc, flags) break; } - if (scbp) { - scbp->control = 0; - scbp->status = 0; - scbp->flags = 0; #ifdef AHC_DEBUG + if (scbp) { ahc->activescbs++; if((ahc_debug & AHC_SHOWSCBCNT) && (ahc->activescbs == ahc->maxhscbs)) printf("%s: Max SCBs active\n", ahc_name(ahc)); -#endif } +#endif splx(opri); @@ -2576,7 +2645,7 @@ ahc_get_scb(ahc, flags) static void ahc_loadseq(ahc) struct ahc_data *ahc; { - static unsigned char seqprog[] = { + static u_char seqprog[] = { # include "aic7xxx_seq.h" }; @@ -2584,12 +2653,10 @@ static void ahc_loadseq(ahc) AHC_OUTSB(ahc, SEQRAM, seqprog, sizeof(seqprog)); - AHC_OUTB(ahc, SEQCTL, FASTMODE|SEQRESET); do { AHC_OUTB(ahc, SEQCTL, SEQRESET|FASTMODE); - - } while (AHC_INB(ahc, SEQADDR0) != 0 && - AHC_INB(ahc, SEQADDR1) != 0); + } while((AHC_INB(ahc, SEQADDR0) != 0) + || (AHC_INB(ahc, SEQADDR1) != 0)); } /* @@ -2606,7 +2673,7 @@ ahc_poll(ahc, wait) if (AHC_INB(ahc, INTSTAT) & INT_PEND) break; } if (wait == 0) { - printf("%s: board not responding\n", ahc_name(ahc)); + printf("%s: board is not responding\n", ahc_name(ahc)); return (EIO); } ahc_intr((void *)ahc); @@ -2619,17 +2686,14 @@ ahc_timeout(arg) { struct scb *scb = (struct scb *)arg; struct ahc_data *ahc; - int s, h, found; + int s, found; u_char bus_state; char channel; s = splbio(); - h = splhigh(); - if (!(scb->flags & SCB_ACTIVE)) { /* Previous timeout took care of me already */ - splx(h); splx(s); return; } @@ -2661,13 +2725,11 @@ ahc_timeout(arg) scb->flags |= SCB_TIMEDOUT; timeout(ahc_timeout, (caddr_t)scb, (scb->xs->timeout * hz) / 1000); - splx(h); splx(s); return; } } ahc->in_timeout = TRUE; - splx(h); /* * Ensure that the card doesn't do anything @@ -2884,8 +2946,8 @@ ahc_reset_device(ahc, target, channel, timedout_scb, xs_error) * Search the QINFIFO. */ { - int saved_queue[AHC_SCB_MAX]; - int queued = AHC_INB(ahc, QINCNT) & ahc->qcntmask; + u_char saved_queue[AHC_SCB_MAX]; + u_char queued = AHC_INB(ahc, QINCNT) & ahc->qcntmask; for (i = 0; i < (queued - found); i++) { saved_queue[i] = AHC_INB(ahc, QINFIFO); diff --git a/sys/dev/ic/aic7xxxreg.h b/sys/dev/ic/aic7xxxreg.h index 240d1f57a93..f53aeab1043 100644 --- a/sys/dev/ic/aic7xxxreg.h +++ b/sys/dev/ic/aic7xxxreg.h @@ -1,5 +1,3 @@ -/* $NetBSD: aic7xxxreg.h,v 1.2 1996/05/20 00:58:10 thorpej Exp $ */ - /* * Aic7xxx register and scratch ram definitions. * @@ -29,6 +27,8 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. + * + * $Id: aic7xxxreg.h,v 1.2 1996/06/27 21:15:49 shawn Exp $ */ /* @@ -434,6 +434,11 @@ * when we were expecting * another msgin byte. */ +#define DATA_OVERRUN 0xe1 /* + * Target attempted to write + * beyond the bounds of its + * command. + */ #define BRKADRINT 0x08 #define SCSIINT 0x04 #define CMDCMPLT 0x02 @@ -739,6 +744,8 @@ #define SAVED_LINKPTR 0x050 #define SAVED_SCBPTR 0x051 +#define ULTRA_ENB 0x052 +#define ULTRA_ENB_B 0x053 #define SCSICONF 0x05a #define RESET_SCSI 0x40 diff --git a/sys/dev/ic/aic7xxxvar.h b/sys/dev/ic/aic7xxxvar.h index 90fe40dfb1f..60ee73ad7c8 100644 --- a/sys/dev/ic/aic7xxxvar.h +++ b/sys/dev/ic/aic7xxxvar.h @@ -1,5 +1,3 @@ -/* $NetBSD: aic7xxxvar.h,v 1.7 1996/05/20 00:58:11 thorpej Exp $ */ - /* * Interface to the generic driver for the aic7xxx based adaptec * SCSI controllers. This is used to implement product specific @@ -31,6 +29,8 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. + * + * $Id: aic7xxxvar.h,v 1.6 1996/06/27 21:15:49 shawn Exp $ */ #ifndef _AIC7XXX_H_ @@ -40,6 +40,21 @@ #include "ahc.h" /* for NAHC from config */ #endif +#if defined(__NetBSD__) +/* + * convert FreeBSD's <sys/queue.h> symbols to NetBSD's + */ +#define STAILQ_ENTRY SIMPLEQ_ENTRY +#define STAILQ_HEAD SIMPLEQ_HEAD +#define STAILQ_INIT SIMPLEQ_INIT +#define STAILQ_INSERT_HEAD SIMPLEQ_INSERT_HEAD +#define STAILQ_INSERT_TAIL SIMPLEQ_INSERT_TAIL +#define STAILQ_REMOVE_HEAD(head, field) \ + SIMPLEQ_REMOVE_HEAD(head, (head)->sqh_first, field) +#define stqh_first sqh_first +#define stqe_next sqe_next +#endif + #if defined(__FreeBSD__) #define AHC_INB(ahc, port) \ inb((ahc)->baseport+(port)) @@ -177,7 +192,7 @@ struct scb { */ /*27*/ u_char prev; /*-----------------end of hardware supported fields----------------*/ - SIMPLEQ_ENTRY(scb) links; /* for chaining */ + STAILQ_ENTRY(scb) links; /* for chaining */ struct scsi_xfer *xs; /* the scsi_xfer for this cmd */ scb_flag flags; u_char position; /* Position in card's scbarray */ @@ -204,19 +219,19 @@ struct ahc_data { * Paged out, non-tagged scbs * indexed by target. */ - SIMPLEQ_HEAD(, scb) free_scbs; /* + STAILQ_HEAD(, scb) free_scbs; /* * SCBs assigned to free slots * on the card. (no paging required) */ - SIMPLEQ_HEAD(, scb) page_scbs; /* + STAILQ_HEAD(, scb) page_scbs; /* * SCBs that will require paging * before use (no assigned slot) */ - SIMPLEQ_HEAD(, scb) waiting_scbs;/* + STAILQ_HEAD(, scb) waiting_scbs;/* * SCBs waiting to be paged in * and started. */ - SIMPLEQ_HEAD(, scb)assigned_scbs;/* + STAILQ_HEAD(, scb)assigned_scbs;/* * SCBs that were waiting but have * now been assigned a slot by * ahc_free_scb. diff --git a/sys/dev/ic/smc93cx6.c b/sys/dev/ic/smc93cx6.c index 10405cd0289..6b5ac52ec21 100644 --- a/sys/dev/ic/smc93cx6.c +++ b/sys/dev/ic/smc93cx6.c @@ -1,5 +1,3 @@ -/* $NetBSD: smc93cx6.c,v 1.1 1996/05/16 03:59:10 mycroft Exp $ */ - /* * Interface for the 93C46/26/06 serial eeprom parts. * @@ -19,6 +17,8 @@ * Daniel M. Eischen. * 4. Modifications may be freely made to this file if the above conditions * are met. + * + * $Id: smc93cx6.c,v 1.2 1996/06/27 21:15:50 shawn Exp $ */ /* @@ -72,16 +72,6 @@ static struct seeprom_cmd { unsigned char bits[3]; } seeprom_read = {3, {1, 1, 0}}; -#if defined(__FreeBSD__) -#define SEEPROM_INB(sd) inb(sd->sd_iobase) -#define SEEPROM_OUTB(sd, value) outb(sd->sd_iobase, value) -#elif defined(__NetBSD__) -#define SEEPROM_INB(sd) \ - bus_io_read_1(sd->sd_bc, sd->sd_ioh, sd->sd_offset) -#define SEEPROM_OUTB(sd, value) \ - bus_io_write_1(sd->sd_bc, sd->sd_ioh, sd->sd_offset, value) -#endif - /* * Wait for the SEERDY to go high; about 800 ns. */ @@ -187,36 +177,3 @@ read_seeprom(sd, buf, start_addr, count) #endif return (1); } - -int -acquire_seeprom(sd) - struct seeprom_descriptor *sd; -{ - int wait; - - /* - * Request access of the memory port. When access is - * granted, SEERDY will go high. We use a 1 second - * timeout which should be near 1 second more than - * is needed. Reason: after the chip reset, there - * should be no contention. - */ - SEEPROM_OUTB(sd, sd->sd_MS); - wait = 1000; /* 1 second timeout in msec */ - while (--wait && ((SEEPROM_INB(sd) & sd->sd_RDY) == 0)) { - DELAY (1000); /* delay 1 msec */ - } - if ((SEEPROM_INB(sd) & sd->sd_RDY) == 0) { - SEEPROM_OUTB(sd, 0); - return (0); - } - return(1); -} - -void -release_seeprom(sd) - struct seeprom_descriptor *sd; -{ - /* Release access to the memory port and the serial EEPROM. */ - SEEPROM_OUTB(sd, 0); -} diff --git a/sys/dev/ic/smc93cx6var.h b/sys/dev/ic/smc93cx6var.h index d1c7c0162cc..017d6aee071 100644 --- a/sys/dev/ic/smc93cx6var.h +++ b/sys/dev/ic/smc93cx6var.h @@ -20,7 +20,7 @@ * 4. Modifications may be freely made to this file if the above conditions * are met. * - * $Id: smc93cx6var.h,v 1.1 1996/05/26 00:27:06 deraadt Exp $ + * $Id: smc93cx6var.h,v 1.2 1996/06/27 21:15:50 shawn Exp $ */ #include <sys/param.h> @@ -59,6 +59,17 @@ struct seeprom_descriptor { * * A failed read attempt returns 0, and a successful read returns 1. */ + +#if defined(__FreeBSD__) +#define SEEPROM_INB(sd) inb(sd->sd_iobase) +#define SEEPROM_OUTB(sd, value) outb(sd->sd_iobase, value) +#elif defined(__NetBSD__) +#define SEEPROM_INB(sd) \ + bus_io_read_1(sd->sd_bc, sd->sd_ioh, sd->sd_offset) +#define SEEPROM_OUTB(sd, value) \ + bus_io_write_1(sd->sd_bc, sd->sd_ioh, sd->sd_offset, value) +#endif + #if defined(__FreeBSD__) int read_seeprom __P((struct seeprom_descriptor *sd, u_int16_t *buf, u_int start_addr, int count)); @@ -66,5 +77,3 @@ int read_seeprom __P((struct seeprom_descriptor *sd, int read_seeprom __P((struct seeprom_descriptor *sd, u_int16_t *buf, bus_io_size_t start_addr, bus_io_size_t count)); #endif -int acquire_seeprom __P((struct seeprom_descriptor *sd)); -void release_seeprom __P((struct seeprom_descriptor *sd)); diff --git a/sys/dev/isa/lpt.c b/sys/dev/isa/lpt.c index 90d6554332e..851b2bcb100 100644 --- a/sys/dev/isa/lpt.c +++ b/sys/dev/isa/lpt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lpt.c,v 1.15 1996/06/25 20:59:05 deraadt Exp $ */ +/* $OpenBSD: lpt.c,v 1.16 1996/06/27 21:15:51 shawn Exp $ */ /* $NetBSD: lpt.c,v 1.39 1996/05/12 23:53:06 mycroft Exp $ */ /* @@ -472,20 +472,22 @@ pushbytes(sc) } else { int s; + s = spltty(); while (sc->sc_count > 0) { /* if the printer is ready for a char, give it one */ if ((sc->sc_state & LPT_OBUSY) == 0) { LPRINTF(("%s: write %d\n", sc->sc_dev.dv_xname, sc->sc_count)); - s = spltty(); (void) lptintr(sc); - splx(s); } error = tsleep((caddr_t)sc, LPTPRI | PCATCH, "lptwrite2", 0); - if (error) + if (error) { + splx(s); return error; + } } + splx(s); } return 0; } @@ -533,7 +535,8 @@ lptintr(arg) bus_chipset_tag_t bc = sc->sc_bc; bus_io_handle_t ioh = sc->sc_ioh; - if (((sc->sc_state & LPT_OPEN) == 0 && sc->sc_count == 0) || (sc->sc_flags & LPT_NOINTR)) + if (((sc->sc_state & LPT_OPEN) == 0 && sc->sc_count == 0) || + (sc->sc_flags & LPT_NOINTR)) return 0; /* is printer online and ready for output */ diff --git a/sys/dev/microcode/aic7xxx/aic7xxx.seq b/sys/dev/microcode/aic7xxx/aic7xxx.seq index 718c8db724a..901fa34eec1 100644 --- a/sys/dev/microcode/aic7xxx/aic7xxx.seq +++ b/sys/dev/microcode/aic7xxx/aic7xxx.seq @@ -1,5 +1,3 @@ -/* $NetBSD: aic7xxx.seq,v 1.3 1996/05/20 00:48:45 thorpej Exp $ */ - /*+M*********************************************************************** *Adaptec 274x/284x/294x device driver for Linux and FreeBSD. * @@ -41,7 +39,7 @@ * *-M************************************************************************/ -VERSION AIC7XXX_SEQ_VER "$NetBSD: aic7xxx.seq,v 1.3 1996/05/20 00:48:45 thorpej Exp $" +VERSION AIC7XXX_SEQ_VER "$Id: aic7xxx.seq,v 1.4 1996/06/27 21:15:52 shawn Exp $" #if defined(__NetBSD__) #include "../../../../dev/ic/aic7xxxreg.h" @@ -85,6 +83,11 @@ reset: start: and FLAGS,0x0f /* clear target specific flags */ mvi SCSISEQ,ENRSELI /* Always allow reselection */ + clr SCSIRATE /* + * We don't know the target we will + * connect to, so default to narrow + * transfers to avoid parity problems. + */ poll_for_work: /* * Are we a twin channel device? @@ -259,13 +262,29 @@ select2: call ndx_dtr mov SCSIRATE,SINDIR +/* + * Initialize Ultra mode setting. + */ + mov FUNCTION1,SCSIID + mov A,FUNCTION1 + and SINDEX,0xdf,SXFRCTL0 /* default to Ultra disabled */ + test SCSIID, 0x80 jnz ultra_b /* Target ID > 7 */ + test SBLKCTL, SELBUSB jnz ultra_b /* Second channel device */ + test ULTRA_ENB,A jz set_sxfrctl0 + or SINDEX, ULTRAEN jmp set_sxfrctl0 +ultra_b: + test ULTRA_ENB_B,A jz set_sxfrctl0 + or SINDEX, ULTRAEN + +set_sxfrctl0: + mov SXFRCTL0,SINDEX + mvi SCSISEQ,ENAUTOATNP /* * ATN on parity errors * for "in" phases */ mvi CLRSINT1,CLRBUSFREE mvi CLRSINT0,0x60 /* CLRSELDI|CLRSELDO */ - /* * Main loop for information transfer phases. If BSY is false, then * we have a bus free condition, expected or not. Otherwise, wait @@ -289,6 +308,7 @@ ITloop: cmp A,P_MESGIN je p_mesgin mvi INTSTAT,BAD_PHASE /* unknown phase - signal driver */ + jmp ITloop /* Try reading the bus again. */ p_dataout: mvi DMAPARAMS,0x7d /* @@ -320,12 +340,29 @@ data_phase_init: or FLAGS, DPHASE /* We have seen a data phase */ data_phase_loop: +/* Guard against overruns */ + test SG_COUNT, 0xff jnz data_phase_inbounds +/* + * Turn on 'Bit Bucket' mode, set the transfer count to + * 16meg and let the target run until it changes phase. + * When the transfer completes, notify the host that we + * had an overrun. + */ + or SXFRCTL1,BITBUCKET + mvi STCNT0,0xff + mvi STCNT1,0xff + mvi STCNT2,0xff + +data_phase_inbounds: /* If we are the last SG block, don't set wideodd. */ cmp SG_COUNT,0x01 jne data_phase_wideodd and DMAPARAMS, 0xbf /* Turn off WIDEODD */ data_phase_wideodd: mov DMAPARAMS call dma +/* Go tell the host about any overruns */ + test SXFRCTL1,BITBUCKET jnz data_phase_overrun + /* Exit if we had an underrun */ test SSTAT0,SDONE jz data_phase_finish /* underrun STCNT != 0 */ @@ -427,6 +464,14 @@ data_phase_finish: mov SCB_RESID_SGCNT, SG_COUNT jmp ITloop +data_phase_overrun: +/* + * Turn off BITBUCKET mode and notify the host + */ + and SXFRCTL1,0x7f /* ~BITBUCKET */ + mvi INTSTAT,DATA_OVERRUN + jmp ITloop + /* * Command phase. Set up the DMA registers and let 'er rip. */ @@ -486,6 +531,7 @@ p_mesgout_start: p_mesgout_loop: test SSTAT1,PHASEMIS jnz p_mesgout_phasemis test SSTAT0,SPIORDY jz p_mesgout_loop + test SSTAT1,PHASEMIS jnz p_mesgout_phasemis cmp DINDEX,1 jne p_mesgout_outb /* last byte? */ mvi CLRSINT1,CLRATNO /* drop ATN */ p_mesgout_outb: @@ -855,6 +901,7 @@ inb_next_wait: test SSTAT0,SPIORDY jz inb_next_wait /* wait for next byte */ inb_first: mov DINDEX,SINDEX + test SSTAT1,PHASEMIS jnz mesgin_phasemis mov DINDIR,SCSIBUSL ret /*read byte directly from bus*/ inb_last: mov NONE,SCSIDATL ret /*dummy read from latch to ACK*/ diff --git a/sys/dev/microcode/aic7xxx/aic7xxx_asm.1 b/sys/dev/microcode/aic7xxx/aic7xxx_asm.1 index be533d3c052..2ff33b78190 100644 --- a/sys/dev/microcode/aic7xxx/aic7xxx_asm.1 +++ b/sys/dev/microcode/aic7xxx/aic7xxx_asm.1 @@ -1,5 +1,3 @@ -.\" $NetBSD: aic7xxx_asm.1,v 1.2 1996/05/20 00:48:47 thorpej Exp $ -.\" .\" Copyright (c) 1994, 1995 .\" Justin T. Gibbs. All rights reserved. .\" diff --git a/sys/dev/microcode/aic7xxx/aic7xxx_asm.c b/sys/dev/microcode/aic7xxx/aic7xxx_asm.c index fd9e8bb4229..109c3e66428 100644 --- a/sys/dev/microcode/aic7xxx/aic7xxx_asm.c +++ b/sys/dev/microcode/aic7xxx/aic7xxx_asm.c @@ -1,5 +1,3 @@ -/* $NetBSD: aic7xxx_asm.c,v 1.4 1996/05/20 00:48:48 thorpej Exp $ */ - /*+M************************************************************************* * Adaptec AIC7770/AIC7870 sequencer code assembler. * @@ -45,7 +43,7 @@ * are token separators. * *-M*************************************************************************/ -static char id[] = "$NetBSD: aic7xxx_asm.c,v 1.4 1996/05/20 00:48:48 thorpej Exp $"; +static char id[] = "$Id: aic7xxx_asm.c,v 1.5 1996/06/27 21:15:54 shawn Exp $"; #include <ctype.h> #include <stdio.h> #include <string.h> diff --git a/sys/dev/microcode/aic7xxx/aic7xxx_reg.h b/sys/dev/microcode/aic7xxx/aic7xxx_reg.h index 9fee01d8527..e589393d9de 100644 --- a/sys/dev/microcode/aic7xxx/aic7xxx_reg.h +++ b/sys/dev/microcode/aic7xxx/aic7xxx_reg.h @@ -28,7 +28,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: aic7xxx_reg.h,v 1.1 1996/05/05 12:42:39 deraadt Exp $ + * $Id: aic7xxx_reg.h,v 1.2 1996/06/27 21:15:54 shawn Exp $ */ /* @@ -372,7 +372,6 @@ #define BUSTIME 0x085 #define BOFF 0xf0 #define BON 0x0f -#define BOFF_60BCLKS 0xf0 /* * Bus Speed (p. 3-45) @@ -396,6 +395,7 @@ #define PAUSE 0x04 #define INTEN 0x02 #define CHIPRST 0x01 +#define CHIPRSTACK 0x01 /* * Interrupt Status (p. 3-50) @@ -434,6 +434,11 @@ * when we were expecting * another msgin byte. */ +#define DATA_OVERRUN 0xe1 /* + * Target attempted to write + * beyond the bounds of its + * command. + */ #define BRKADRINT 0x08 #define SCSIINT 0x04 #define CMDCMPLT 0x02 @@ -561,7 +566,7 @@ #define SCB_NEXT 0x0ba #define SCB_PREV 0x0bb -#ifdef linux +#ifdef __linux__ #define SG_SIZEOF 0x0c /* sizeof(struct scatterlist) */ #else #define SG_SIZEOF 0x08 /* sizeof(struct ahc_dma) */ @@ -739,13 +744,18 @@ #define SAVED_LINKPTR 0x050 #define SAVED_SCBPTR 0x051 +#define ULTRA_ENB 0x052 +#define ULTRA_ENB_B 0x053 #define SCSICONF 0x05a +#define RESET_SCSI 0x40 + #define HOSTCONF 0x05d #define HA_274_BIOSCTRL 0x05f #define BIOSMODE 0x30 #define BIOSDISABLED 0x30 +#define CHANNEL_B_PRIMARY 0x08 /* Message codes */ #define MSG_EXTENDED 0x01 diff --git a/sys/dev/pci/ahc_pci.c b/sys/dev/pci/ahc_pci.c index d1f96318df4..1e92b37c7cf 100644 --- a/sys/dev/pci/ahc_pci.c +++ b/sys/dev/pci/ahc_pci.c @@ -1,5 +1,3 @@ -/* $NetBSD: ahc_pci.c,v 1.2 1996/05/20 00:56:39 thorpej Exp $ */ - /* * Product specific probe and attach routines for: * 3940, 2940, aic7880, aic7870, aic7860 and aic7850 SCSI controllers @@ -30,6 +28,8 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. + * + * $Id: ahc_pci.c,v 1.2 1996/06/27 21:15:55 shawn Exp $ */ #if defined(__FreeBSD__) @@ -44,9 +44,7 @@ #if defined(__NetBSD__) #include <sys/device.h> #include <machine/bus.h> -#ifdef __alpha__ #include <machine/intr.h> -#endif #endif /* defined(__NetBSD__) */ #include <scsi/scsi_all.h> @@ -176,6 +174,8 @@ struct seeprom_config { }; static void load_seeprom __P((struct ahc_data *ahc)); +static int acquire_seeprom __P((struct seeprom_descriptor *sd)); +static void release_seeprom __P((struct seeprom_descriptor *sd)); static u_char aic3940_count; @@ -421,41 +421,6 @@ ahc_pci_attach(parent, self, aux) } } - /* - * Ensure that we are using good values for the PCI burst size - * and latency timer. - */ - { -#if defined(__FreeBSD__) - u_long csize_lattime = pci_conf_read(config_id, CSIZE_LATTIME); -#elif defined(__NetBSD__) - u_long csize_lattime = - pci_conf_read(pa->pa_pc, pa->pa_tag, CSIZE_LATTIME); -#endif - - if((csize_lattime & CACHESIZE) == 0) { - /* default to 8DWDs. What's the PCI define for this? */ - csize_lattime |= 8; - } - if((csize_lattime & LATTIME) == 0) { - /* Default to 64 PCLKS (is this a good value?) */ - /* This may also be availble in the SEEPROM?? */ - csize_lattime |= (64 << 8); - } - if(bootverbose) - printf("ahc%d: BurstLen = %ldDWDs, " - "Latency Timer = %ldPCLKS\n", - unit, - csize_lattime & CACHESIZE, - (csize_lattime >> 8) & 0xff); -#if defined(__FreeBSD__) - pci_conf_write(config_id, CSIZE_LATTIME, csize_lattime); -#elif defined(__NetBSD__) - pci_conf_write(pa->pa_pc, pa->pa_tag, CSIZE_LATTIME, - csize_lattime); -#endif - } - #if defined(__FreeBSD__) if(!(ahc = ahc_alloc(unit, io_port, ahc_t, ahc_f))) return; /* XXX PCI code should take return status */ @@ -572,10 +537,20 @@ ahc_pci_attach(parent, self, aux) /* See if someone else set us up already */ u_long i; for(i = TARG_SCRATCH; i < 0x60; i++) { - if(AHC_INB(ahc, i) != 0xff) + if(AHC_INB(ahc, i) != 0x00) break; } - if(i != 0x60) { + if(i == TARG_SCRATCH) { + /* + * Try looking for all ones. You can get + * either. + */ + for (i = TARG_SCRATCH; i < 0x60; i++) { + if(AHC_INB(ahc, i) != 0xff) + break; + } + } + if((i != 0x60) && (our_id != 0)) { printf("%s: Using left over BIOS settings\n", ahc_name(ahc)); ahc->flags &= ~AHC_USEDEFAULTS; @@ -608,7 +583,6 @@ ahc_pci_attach(parent, self, aux) splx(opri); ahc_attach(ahc); - return; } /* @@ -677,7 +651,7 @@ load_seeprom(ahc) int i; int max_targ = sc.max_targets & CFMAXTARG; - for(i = 0; i <= max_targ; i++){ + for(i = 0; i < max_targ; i++){ u_char target_settings; target_settings = (sc.device_flags[i] & CFXFER) << 4; if (sc.device_flags[i] & CFSYNCH) @@ -712,4 +686,37 @@ load_seeprom(ahc) } } +static int +acquire_seeprom(sd) + struct seeprom_descriptor *sd; +{ + int wait; + + /* + * Request access of the memory port. When access is + * granted, SEERDY will go high. We use a 1 second + * timeout which should be near 1 second more than + * is needed. Reason: after the chip reset, there + * should be no contention. + */ + SEEPROM_OUTB(sd, sd->sd_MS); + wait = 1000; /* 1 second timeout in msec */ + while (--wait && ((SEEPROM_INB(sd) & sd->sd_RDY) == 0)) { + DELAY (1000); /* delay 1 msec */ + } + if ((SEEPROM_INB(sd) & sd->sd_RDY) == 0) { + SEEPROM_OUTB(sd, 0); + return (0); + } + return(1); +} + +static void +release_seeprom(sd) + struct seeprom_descriptor *sd; +{ + /* Release access to the memory port and the serial EEPROM. */ + SEEPROM_OUTB(sd, 0); +} + #endif /* NPCI > 0 */ |