Merge in changes for NetBSD/OpenBSD.

Add a panic for attempts to page in a non paged out SCB.

Re-order some of the interrupt routine for better performance.

NetBSD/OpenBSD support Submitted by:Noriyuki Soda <soda@sra.co.jp>,
				    Pete Bentley <pete@demon.net>,
				    Charles M. Hannum <mycroft@mit.edu>,
				    Theo de Raadt <deraadt@theos.com>
This commit is contained in:
Justin T. Gibbs 1996-05-30 07:19:59 +00:00
parent 56981243dd
commit 0262313ddc
4 changed files with 843 additions and 494 deletions

View File

@ -18,7 +18,7 @@
* 4. Modifications may be freely made to this file if the above conditions
* are met.
*
* $Id: 93cx6.c,v 1.3 1995/11/14 09:58:47 phk Exp $
* $Id: 93cx6.c,v 1.4 1995/11/20 12:14:02 phk Exp $
*/
/*
@ -55,8 +55,13 @@
#include <sys/param.h>
#include <sys/systm.h>
#if defined(__FreeBSD__)
#include <machine/clock.h>
#include <i386/scsi/93cx6.h>
#elif defined(__NetBSD__)
#include <machine/bus.h>
#include <dev/ic/smc93cx6var.h>
#endif
/*
* Right now, we only have to read the SEEPROM. But we make it easier to
@ -67,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 */ \
}
@ -80,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;
}
/*
@ -138,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:");

View File

@ -20,11 +20,29 @@
* 4. Modifications may be freely made to this file if the above conditions
* are met.
*
* $Id: 93cx6.h,v 1.1 1995/07/04 21:16:12 gibbs Exp $
* $Id: 93cx6.h,v 1.2 1995/09/05 23:52:00 gibbs Exp $
*/
#include <sys/param.h>
#if !defined(__NetBSD__)
#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
@ -41,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

File diff suppressed because it is too large Load Diff

View File

@ -30,13 +30,54 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: aic7xxx.h,v 1.26 1996/04/28 19:21:20 gibbs Exp $
* $Id: aic7xxx.h,v 1.27 1996/05/10 16:21:05 gibbs Exp $
*/
#ifndef _AIC7XXX_H_
#define _AIC7XXX_H_
#if defined(__FreeBSD__)
#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))
#define AHC_INSB(ahc, port, valp, size) \
insb((ahc)->baseport+(port), valp, size)
#define AHC_OUTB(ahc, port, val) \
outb((ahc)->baseport+(port), val)
#define AHC_OUTSB(ahc, port, valp, size) \
outsb((ahc)->baseport+(port), valp, size)
#define AHC_OUTSL(ahc, port, valp, size) \
outsl((ahc)->baseport+(port), valp, size)
#elif defined(__NetBSD__)
#define AHC_INB(ahc, port) \
bus_io_read_1((ahc)->sc_bc, (ahc)->sc_ioh, port)
#define AHC_INSB(ahc, port, valp, size) \
bus_io_read_multi_1((ahc)->sc_bc, (ahc)->sc_ioh, port, valp, size)
#define AHC_OUTB(ahc, port, val) \
bus_io_write_1((ahc)->sc_bc, (ahc)->sc_ioh, port, val)
#define AHC_OUTSB(ahc, port, valp, size) \
bus_io_write_multi_1((ahc)->sc_bc, (ahc)->sc_ioh, port, valp, size)
#define AHC_OUTSL(ahc, port, valp, size) \
bus_io_write_multi_4((ahc)->sc_bc, (ahc)->sc_ioh, port, valp, size)
#endif
#define AHC_NSEG 256 /* number of dma segments supported */
@ -50,7 +91,9 @@
typedef unsigned long int physaddr;
#if defined(__FreeBSD__)
extern u_long ahc_unit;
#endif
struct ahc_dma_seg {
physaddr addr;
@ -158,10 +201,19 @@ struct scb {
};
struct ahc_data {
#if defined(__FreeBSD__)
int unit;
#elif defined(__NetBSD__)
struct device sc_dev;
void *sc_ih;
bus_chipset_tag_t sc_bc;
bus_io_handle_t sc_ioh;
#endif
ahc_type type;
ahc_flag flags;
#if defined(__FreeBSD__)
u_long baseport;
#endif
struct scb *scbarray[AHC_SCB_MAX]; /* Mirror boards scbarray */
struct scb *pagedout_ntscbs[16];/*
* Paged out, non-tagged scbs
@ -223,11 +275,26 @@ struct ahc_data {
extern int ahc_debug; /* Initialized in i386/scsi/aic7xxx.c */
#endif
#if defined(__FreeBSD__)
char *ahc_name __P((struct ahc_data *ahc));
void ahc_reset __P((u_long iobase));
struct ahc_data *ahc_alloc __P((int unit, u_long io_base, ahc_type type, ahc_flag flags));
#elif defined(__NetBSD__)
#define ahc_name(ahc) (ahc)->sc_dev.dv_xname
void ahc_reset __P((char *devname, bus_chipset_tag_t bc, bus_io_handle_t ioh));
void ahc_construct __P((struct ahc_data *ahc, bus_chipset_tag_t bc, bus_io_handle_t ioh, ahc_type type, ahc_flag flags));
#endif
void ahc_free __P((struct ahc_data *));
int ahc_init __P((struct ahc_data *));
int ahc_attach __P((struct ahc_data *));
#if defined(__FreeBSD__)
void ahc_intr __P((void *arg));
#elif defined(__NetBSD__)
int ahc_intr __P((void *arg));
#endif
#endif /* _AIC7XXX_H_ */