NetBSD/sys/arch/acorn32/podulebus/sfasvar.h

269 lines
8.8 KiB
C

/* $NetBSD: sfasvar.h,v 1.3 2003/04/09 01:54:43 thorpej Exp $ */
/*
* Copyright (c) 1995 Daniel Widenfalk
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Daniel Widenfalk
* for the NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 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.
*/
#ifndef _SFASVAR_H_
#define _SFASVAR_H_
#ifndef _SFASREG_H_
#include <acorn32/podulebus/sfasreg.h>
#endif
/*
* MAXCHAIN is the anticipated maximum number of chain blocks needed. This
* assumes that we are NEVER requested to transfer more than MAXPHYS bytes.
*/
#define MAXCHAIN (MAXPHYS/PAGE_SIZE+2)
/*
* Maximum number of requests standing by. Could be anything, but I think 9
* looks nice :-) NOTE: This does NOT include requests already started!
*/
#define MAXPENDING 9 /* 7 IDs + 2 extra */
/*
* DMA chain block. If flg == SFAS_CHAIN_PRG or flg == SFAS_CHAIN_BUMP then
* ptr is a VIRTUAL adress. If flg == SFAS_CHAIN_DMA then ptr is a PHYSICAL
* adress.
*/
struct sfas_dma_chain {
void *ptr;
u_short len;
short flg;
};
#define SFAS_CHAIN_DMA 0x00
#define SFAS_CHAIN_BUMP 0x01
#define SFAS_CHAIN_PRG 0x02
/*
* This struct contains the necessary info for a pending request. Pointer to
* a scsipi_xfer struct.
*/
struct sfas_pending {
TAILQ_ENTRY(sfas_pending) link;
struct scsipi_xfer *xs;
};
/*
* nexus contains all active data for one SCSI unit. Parts of the info in this
* struct survives between scsi commands.
*/
struct nexus {
struct scsipi_xfer *xs; /* Pointer to request */
u_char ID; /* ID message to be sent */
u_char clen; /* scsi command length + */
u_char cbuf[14]; /* the actual command bytes */
struct sfas_dma_chain dma[MAXCHAIN]; /* DMA chain blocks */
short max_link; /* Maximum used of above */
short cur_link; /* Currently handled block */
u_char *buf; /* Virtual adress of data */
int len; /* Bytes left to transfer */
void *dma_buf; /* Current DMA adress */
int dma_len; /* Current DMA length */
void *dma_blk_ptr; /* Current chain adress */
int dma_blk_len; /* Current chain length */
u_char dma_blk_flg; /* Current chain flags */
u_char state; /* Nexus state, see below */
u_short flags; /* Nexus flags, see below */
short period; /* Sync period to request */
u_char offset; /* Sync offset to request */
u_char syncper; /* FAS216 variable storage */
u_char syncoff; /* FAS216 variable storage */
u_char config3; /* FAS216 variable storage */
u_char lun_unit; /* (Lun<<4) | Unit of nexus */
u_char status; /* Status byte from unit*/
};
/* SCSI nexus_states */
#define SFAS_NS_IDLE 0 /* Nexus idle */
#define SFAS_NS_SELECTED 1 /* Last command was a SELECT command */
#define SFAS_NS_DATA_IN 2 /* Last command was a TRANSFER_INFO */
/* command during a data in phase */
#define SFAS_NS_DATA_OUT 3 /* Last command was a TRANSFER_INFO */
/* command during a data out phase */
#define SFAS_NS_STATUS 4 /* We have send a COMMAND_COMPLETE */
/* command and are awaiting status */
#define SFAS_NS_MSG_IN 5 /* Last phase was MESSAGE IN */
#define SFAS_NS_MSG_OUT 6 /* Last phase was MESSAGE OUT */
#define SFAS_NS_SVC 7 /* We have sent the command */
#define SFAS_NS_DISCONNECTING 8 /* We have received a disconnect msg */
#define SFAS_NS_DISCONNECTED 9 /* We are disconnected */
#define SFAS_NS_RESELECTED 10 /* We was reselected */
#define SFAS_NS_DONE 11 /* Done. Prephsase to FINISHED */
#define SFAS_NS_FINISHED 12 /* Realy done. Call scsi_done */
#define SFAS_NS_RESET 13 /* We are reseting this unit */
/* SCSI nexus flags */
#define SFAS_NF_UNIT_BUSY 0x0001 /* Unit is not available */
#define SFAS_NF_SELECT_ME 0x0002 /* Nexus is set up, waiting for bus */
#define SFAS_NF_HAS_MSG 0x0010 /* We have received a complete msg */
#define SFAS_NF_DO_SDTR 0x0020 /* We should send a SDTR */
#define SFAS_NF_SDTR_SENT 0x0040 /* We have sent a SDTR */
#define SFAS_NF_SYNC_TESTED 0x0080 /* We have negotiated sync */
#define SFAS_NF_RESET 0x0100 /* Reset this nexus */
#define SFAS_NF_IMMEDIATE 0x0200 /* We are operating from sfasicmd */
#define SFAS_NF_RETRY_SELECT 0x1000 /* Selection needs retrying */
#define SFAS_NF_DEBUG 0x8000 /* As it says: DEBUG */
struct sfas_softc {
struct device sc_dev; /* System required struct */
struct scsipi_channel sc_channel;
struct scsipi_adapter sc_adapter;
void *sc_ih;
struct evcnt sc_intrcnt;
TAILQ_HEAD(,sfas_pending) sc_xs_pending;
TAILQ_HEAD(,sfas_pending) sc_xs_free;
struct sfas_pending sc_xs_store[MAXPENDING];
sfas_regmap_p sc_fas; /* FAS216 Address */
void *sc_spec; /* Board-specific data */
u_char *sc_bump_va; /* Bumpbuf virtual adr */
void *sc_bump_pa; /* Bumpbuf physical adr */
int sc_bump_sz; /* Bumpbuf size */
/* Configuration registers, must be set BEFORE sfasinitialize */
u_char sc_clock_freq;
u_short sc_timeout;
u_char sc_host_id;
u_char sc_config_flags;
/* Generic DMA functions */
int (*sc_setup_dma)(void *, void *, int, int);
int (*sc_build_dma_chain)(void *, void *, void *,
int);
int (*sc_need_bump)(void *, void *, int);
/* Optional replacement ixfer */
void (*sc_ixfer)(void *, int);
/* Generic Led data */
int sc_led_status;
void (*sc_led)(void *, int);
/* Nexus list */
struct nexus sc_nexus[8];
struct nexus *sc_cur_nexus;
struct nexus *sc_sel_nexus;
/* Current transfer data */
u_char *sc_buf; /* va */
int sc_len;
void *sc_dma_buf; /* pa */
int sc_dma_len;
void *sc_dma_blk_ptr;
int sc_dma_blk_len;
short sc_dma_blk_flg;
struct sfas_dma_chain *sc_chain; /* Current DMA chain */
short sc_max_link;
short sc_cur_link;
/* Interrupt registers */
u_char sc_status;
u_char sc_interrupt;
u_char sc_resel[2];
u_char sc_units_disconnected;
/* Storage for FAS216 config registers (current values) */
u_char sc_config1;
u_char sc_config2;
u_char sc_config3;
u_char sc_clock_conv_fact;
u_char sc_timeout_val;
u_char sc_clock_period;
u_char sc_msg_in[7];
u_char sc_msg_in_len;
u_char sc_msg_out[7];
u_char sc_msg_out_len;
u_char sc_unit;
u_char sc_lun;
u_char sc_flags;
};
#define SFAS_DMA_READ 0
#define SFAS_DMA_WRITE 1
#define SFAS_DMA_CLEAR 2
/* sc_flags */
#define SFAS_ACTIVE 0x01
#define SFAS_DONT_WAIT 0x02
/* SCSI Selection modes */
#define SFAS_SELECT 0x00 /* Normal selection: No sync, no resel */
#define SFAS_SELECT_R 0x01 /* Reselection allowed */
#define SFAS_SELECT_S 0x02 /* Synchronous transfer allowed */
#define SFAS_SELECT_I 0x04 /* Selection for sfasicmd */
#define SFAS_SELECT_K 0x08 /* Send a BUS DEVICE RESET message (Kill) */
/* Nice abbreviations of the above */
#define SFAS_SELECT_RS (SFAS_SELECT_R|SFAS_SELECT_S)
#define SFAS_SELECT_RI (SFAS_SELECT_R|SFAS_SELECT_I)
#define SFAS_SELECT_SI (SFAS_SELECT_S|SFAS_SELECT_I)
#define SFAS_SELECT_RSI (SFAS_SELECT_R|SFAS_SELECT_S|SFAS_SELECT_I)
/* sc_config_flags */
#define SFAS_NO_SYNCH 0x01 /* Disable synchronous transfer */
#define SFAS_NO_DMA 0x02 /* Do not use DMA! EVER! */
#define SFAS_NO_RESELECT 0x04 /* Do not allow relesection */
#define SFAS_SLOW_CABLE 0x08 /* Cable is "unsafe" for fast scsi-2 */
#define SFAS_SLOW_START 0x10 /* There are slow starters on the bus */
void sfasinitialize __P((struct sfas_softc *sc));
void sfas_minphys __P((struct buf *bp));
void sfas_scsi_request __P((struct scsipi_channel *,
scsipi_adapter_req_t, void *));
void sfasintr __P((struct sfas_softc *dev));
#endif /* _SFASVAR_H_ */