1 /* $NetBSD: escvar.h,v 1.2 2002/02/18 19:55:01 bjh21 Exp $ */ 2 3 /* 4 * Copyright (c) 1995 Daniel Widenfalk 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Daniel Widenfalk 17 * for the NetBSD Project. 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #ifndef _ESCVAR_H_ 34 #define _ESCVAR_H_ 35 36 #ifndef _ESCREG_H_ 37 #include <acorn32/podulebus/escreg.h> 38 #endif 39 40 /* 41 * MAXCHAIN is the anticipated maximum number of chain blocks needed. This 42 * assumes that we are NEVER requested to transfer more than MAXPHYS bytes. 43 */ 44 #define MAXCHAIN (MAXPHYS/NBPG+2) 45 46 /* 47 * Maximum number of requests standing by. Could be anything, but I think 9 48 * looks nice :-) NOTE: This does NOT include requests already started! 49 */ 50 #define MAXPENDING 9 /* 7 IDs + 2 extra */ 51 52 /* 53 * DMA chain block. If flg == ESC_CHAIN_PRG or flg == ESC_CHAIN_BUMP then 54 * ptr is a VIRTUAL adress. If flg == ESC_CHAIN_DMA then ptr is a PHYSICAL 55 * adress. 56 */ 57 struct esc_dma_chain { 58 vm_offset_t ptr; 59 u_short len; 60 short flg; 61 }; 62 #define ESC_CHAIN_DMA 0x00 63 #define ESC_CHAIN_BUMP 0x01 64 #define ESC_CHAIN_PRG 0x02 65 66 67 /* 68 * This struct contains the necessary info for a pending request. Pointer to 69 * a scsipi_xfer struct. 70 */ 71 struct esc_pending { 72 TAILQ_ENTRY(esc_pending) link; 73 struct scsipi_xfer *xs; 74 }; 75 76 /* 77 * nexus contains all active data for one SCSI unit. Parts of the info in this 78 * struct survives between scsi commands. 79 */ 80 struct nexus { 81 struct scsipi_xfer *xs; /* Pointer to request */ 82 83 u_char ID; /* ID message to be sent */ 84 u_char clen; /* scsi command length + */ 85 u_char cbuf[14]; /* the actual command bytes */ 86 87 struct esc_dma_chain dma[MAXCHAIN]; /* DMA chain blocks */ 88 short max_link; /* Maximum used of above */ 89 short cur_link; /* Currently handled block */ 90 91 u_char *buf; /* Virtual adress of data */ 92 int len; /* Bytes left to transfer */ 93 94 vm_offset_t dma_buf; /* Current DMA adress */ 95 int dma_len; /* Current DMA length */ 96 97 vm_offset_t dma_blk_ptr; /* Current chain adress */ 98 int dma_blk_len; /* Current chain length */ 99 u_char dma_blk_flg; /* Current chain flags */ 100 101 u_char state; /* Nexus state, see below */ 102 u_short flags; /* Nexus flags, see below */ 103 104 short period; /* Sync period to request */ 105 u_char offset; /* Sync offset to request */ 106 107 u_char syncper; /* FAS216 variable storage */ 108 u_char syncoff; /* FAS216 variable storage */ 109 u_char config3; /* FAS216 variable storage */ 110 111 u_char lun_unit; /* (Lun<<4) | Unit of nexus */ 112 u_char status; /* Status byte from unit*/ 113 114 }; 115 116 /* SCSI nexus_states */ 117 #define ESC_NS_IDLE 0 /* Nexus idle */ 118 #define ESC_NS_SELECTED 1 /* Last command was a SELECT command */ 119 #define ESC_NS_DATA_IN 2 /* Last command was a TRANSFER_INFO */ 120 /* command during a data in phase */ 121 #define ESC_NS_DATA_OUT 3 /* Last command was a TRANSFER_INFO */ 122 /* command during a data out phase */ 123 #define ESC_NS_STATUS 4 /* We have send a COMMAND_COMPLETE */ 124 /* command and are awaiting status */ 125 #define ESC_NS_MSG_IN 5 /* Last phase was MESSAGE IN */ 126 #define ESC_NS_MSG_OUT 6 /* Last phase was MESSAGE OUT */ 127 #define ESC_NS_SVC 7 /* We have sent the command */ 128 #define ESC_NS_DISCONNECTING 8 /* We have received a disconnect msg */ 129 #define ESC_NS_DISCONNECTED 9 /* We are disconnected */ 130 #define ESC_NS_RESELECTED 10 /* We was reselected */ 131 #define ESC_NS_DONE 11 /* Done. Prephsase to FINISHED */ 132 #define ESC_NS_FINISHED 12 /* Realy done. Call scsi_done */ 133 #define ESC_NS_RESET 13 /* We are reseting this unit */ 134 135 /* SCSI nexus flags */ 136 #define ESC_NF_UNIT_BUSY 0x0001 /* Unit is not available */ 137 138 #define ESC_NF_SELECT_ME 0x0002 /* Nexus is set up, waiting for bus */ 139 140 #define ESC_NF_HAS_MSG 0x0010 /* We have received a complete msg */ 141 142 #define ESC_NF_DO_SDTR 0x0020 /* We should send a SDTR */ 143 #define ESC_NF_SDTR_SENT 0x0040 /* We have sent a SDTR */ 144 #define ESC_NF_SYNC_TESTED 0x0080 /* We have negotiated sync */ 145 146 #define ESC_NF_RESET 0x0100 /* Reset this nexus */ 147 #define ESC_NF_IMMEDIATE 0x0200 /* We are operating from escicmd */ 148 149 #define ESC_NF_RETRY_SELECT 0x1000 /* Selection needs retrying */ 150 151 #define ESC_NF_DEBUG 0x8000 /* As it says: DEBUG */ 152 153 struct esc_softc { 154 struct device sc_dev; /* System required struct */ 155 struct scsipi_channel sc_channel; /* For sub devices */ 156 struct scsipi_adapter sc_adapter; 157 irqhandler_t sc_ih; /* Interrupt chain struct */ 158 159 TAILQ_HEAD(,esc_pending) sc_xs_pending; 160 TAILQ_HEAD(,esc_pending) sc_xs_free; 161 struct esc_pending sc_xs_store[MAXPENDING]; 162 163 esc_regmap_p sc_esc; /* FAS216 Address */ 164 void *sc_spec; /* Board-specific data */ 165 166 u_char *sc_bump_va; /* Bumpbuf virtual adr */ 167 vm_offset_t sc_bump_pa; /* Bumpbuf physical adr */ 168 int sc_bump_sz; /* Bumpbuf size */ 169 170 /* Configuration registers, must be set BEFORE escinitialize */ 171 u_char sc_clock_freq; 172 u_short sc_timeout; 173 u_char sc_host_id; 174 u_char sc_config_flags; 175 176 /* Generic DMA functions */ 177 int (*sc_setup_dma)(struct esc_softc *, void *, 178 int, int); 179 int (*sc_build_dma_chain)(struct esc_softc *, 180 struct esc_dma_chain *, void *, int); 181 int (*sc_need_bump)(struct esc_softc *, void *, 182 int); 183 184 /* Generic Led data */ 185 int sc_led_status; 186 void (*sc_led)(struct esc_softc *, int); 187 188 /* Nexus list */ 189 struct nexus sc_nexus[8]; 190 struct nexus *sc_cur_nexus; 191 struct nexus *sc_sel_nexus; 192 193 /* Current transfer data */ 194 u_char *sc_buf; /* va */ 195 int sc_len; 196 197 vm_offset_t sc_dma_buf; /* pa */ 198 int sc_dma_len; 199 vm_offset_t sc_dma_blk_ptr; 200 int sc_dma_blk_len; 201 short sc_dma_blk_flg; 202 203 struct esc_dma_chain *sc_chain; /* Current DMA chain */ 204 short sc_max_link; 205 short sc_cur_link; 206 207 /* Interrupt registers */ 208 u_char sc_status; 209 u_char sc_interrupt; 210 u_char sc_resel[2]; 211 212 u_char sc_units_disconnected; 213 214 /* Storage for FAS216 config registers (current values) */ 215 u_char sc_config1; 216 u_char sc_config2; 217 u_char sc_config3; 218 u_char sc_config4; 219 u_char sc_clock_conv_fact; 220 u_char sc_timeout_val; 221 u_char sc_clock_period; 222 223 u_char sc_msg_in[7]; 224 u_char sc_msg_in_len; 225 226 u_char sc_msg_out[7]; 227 u_char sc_msg_out_len; 228 229 u_char sc_unit; 230 u_char sc_lun; 231 u_char sc_flags; 232 }; 233 234 #define ESC_DMA_READ 0 235 #define ESC_DMA_WRITE 1 236 #define ESC_DMA_CLEAR 2 237 238 /* sc_flags */ 239 #define ESC_ACTIVE 0x01 240 #define ESC_DONT_WAIT 0x02 241 242 /* SCSI Selection modes */ 243 #define ESC_SELECT 0x00 /* Normal selection: No sync, no resel */ 244 #define ESC_SELECT_R 0x01 /* Reselection allowed */ 245 #define ESC_SELECT_S 0x02 /* Synchronous transfer allowed */ 246 #define ESC_SELECT_I 0x04 /* Selection for escicmd */ 247 #define ESC_SELECT_K 0x08 /* Send a BUS DEVICE RESET message (Kill) */ 248 249 /* Nice abbreviations of the above */ 250 #define ESC_SELECT_RS (ESC_SELECT_R|ESC_SELECT_S) 251 #define ESC_SELECT_RI (ESC_SELECT_R|ESC_SELECT_I) 252 #define ESC_SELECT_SI (ESC_SELECT_S|ESC_SELECT_I) 253 #define ESC_SELECT_RSI (ESC_SELECT_R|ESC_SELECT_S|ESC_SELECT_I) 254 255 /* sc_config_flags */ 256 #define ESC_NO_SYNCH 0x01 /* Disable synchronous transfer */ 257 #define ESC_NO_DMA 0x02 /* Do not use DMA! EVER! */ 258 #define ESC_NO_RESELECT 0x04 /* Do not allow relesection */ 259 #define ESC_SLOW_CABLE 0x08 /* Cable is "unsafe" for fast scsi-2 */ 260 #define ESC_SLOW_START 0x10 /* There are slow starters on the bus */ 261 262 void escinitialize __P((struct esc_softc *sc)); 263 void esc_minphys __P((struct buf *bp)); 264 void esc_scsi_request __P((struct scsipi_channel *, 265 scsipi_adapter_req_t, void *)); 266 void escintr __P((struct esc_softc *dev)); 267 268 #endif /* _ESCVAR_H_ */ 269