summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorshawn <shawn@openbsd.org>1996-06-27 21:15:44 +0000
committershawn <shawn@openbsd.org>1996-06-27 21:15:44 +0000
commit772afd3a90efd893cbbe788a45221b31e180bdf4 (patch)
tree9d788aabb547a112bcb5afb5e5a6e07bdea8de61
parentWe now support bug reports using a modified version of send-pr(1) that (diff)
downloadwireguard-openbsd-772afd3a90efd893cbbe788a45221b31e180bdf4.tar.xz
wireguard-openbsd-772afd3a90efd893cbbe788a45221b31e180bdf4.zip
new 2940 driver merged from freebsd sources 960623
-rw-r--r--sys/dev/eisa/ahc_eisa.c7
-rw-r--r--sys/dev/eisa/aic7770.c298
-rw-r--r--sys/dev/ic/93cx6.c120
-rw-r--r--sys/dev/ic/93cx6.h46
-rw-r--r--sys/dev/ic/aic7xxx.c474
-rw-r--r--sys/dev/ic/aic7xxxreg.h11
-rw-r--r--sys/dev/ic/aic7xxxvar.h29
-rw-r--r--sys/dev/ic/smc93cx6.c47
-rw-r--r--sys/dev/ic/smc93cx6var.h15
-rw-r--r--sys/dev/isa/lpt.c13
-rw-r--r--sys/dev/microcode/aic7xxx/aic7xxx.seq55
-rw-r--r--sys/dev/microcode/aic7xxx/aic7xxx_asm.12
-rw-r--r--sys/dev/microcode/aic7xxx/aic7xxx_asm.c4
-rw-r--r--sys/dev/microcode/aic7xxx/aic7xxx_reg.h16
-rw-r--r--sys/dev/pci/ahc_pci.c93
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 */