]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/advansys/adwlib.h
This commit was generated by cvs2svn to compensate for changes in r53793,
[FreeBSD/FreeBSD.git] / sys / dev / advansys / adwlib.h
1 /*
2  * Definitions for low level routines and data structures
3  * for the Advanced Systems Inc. SCSI controllers chips.
4  *
5  * Copyright (c) 1998 Justin T. Gibbs.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions, and the following disclaimer,
13  *    without modification, immediately at the beginning of the file.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. The name of the author may not be used to endorse or promote products
18  *    derived from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
24  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  * $FreeBSD$
33  */
34 /*
35  * Ported from:
36  * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
37  *     
38  * Copyright (c) 1995-1998 Advanced System Products, Inc.
39  * All Rights Reserved.
40  *   
41  * Redistribution and use in source and binary forms, with or without
42  * modification, are permitted provided that redistributions of source
43  * code retain the above copyright notice and this comment without
44  * modification.
45  */
46
47 #ifndef _ADWLIB_H_
48 #define _ADWLIB_H_
49
50 #include "opt_adw.h"
51
52 #include <stddef.h>     /* for offsetof */
53
54 #include <dev/advansys/adwmcode.h>
55
56 #define ADW_DEF_MAX_HOST_QNG    253
57 #define ADW_DEF_MIN_HOST_QNG    16
58 #define ADW_DEF_MAX_DVC_QNG     63
59 #define ADW_DEF_MIN_DVC_QNG     4
60
61 #define ADW_MAX_TID             15
62 #define ADW_MAX_LUN             7
63
64 /*
65  * Board Register offsets.
66  */
67 #define ADW_INTR_STATUS_REG                     0x0000
68 #define         ADW_INTR_STATUS_INTRA           0x01
69 #define         ADW_INTR_STATUS_INTRB           0x02
70 #define         ADW_INTR_STATUS_INTRC           0x04
71
72
73 #define ADW_SIGNATURE_WORD                      0x0000
74 #define          ADW_CHIP_ID_WORD               0x04C1
75
76 #define ADW_SIGNATURE_BYTE                      0x0001
77 #define          ADW_CHIP_ID_BYTE               0x25    
78
79 #define ADW_INTR_ENABLES                        0x0002  /*8 bit */
80 #define         ADW_INTR_ENABLE_HOST_INTR       0x01
81 #define         ADW_INTR_ENABLE_SEL_INTR        0x02
82 #define         ADW_INTR_ENABLE_DPR_INTR        0x04
83 #define         ADW_INTR_ENABLE_RTA_INTR        0x08
84 #define         ADW_INTR_ENABLE_RMA_INTR        0x10
85 #define         ADW_INTR_ENABLE_RST_INTR        0x20
86 #define         ADW_INTR_ENABLE_DPE_INTR        0x40
87 #define         ADW_INTR_ENABLE_GLOBAL_INTR     0x80
88
89 #define ADW_CTRL_REG                            0x0002  /*16 bit*/
90 #define         ADW_CTRL_REG_HOST_INTR          0x0100
91 #define         ADW_CTRL_REG_SEL_INTR           0x0200
92 #define         ADW_CTRL_REG_DPR_INTR           0x0400
93 #define         ADW_CTRL_REG_RTA_INTR           0x0800
94 #define         ADW_CTRL_REG_RMA_INTR           0x1000
95 #define         ADW_CTRL_REG_RES_BIT14          0x2000
96 #define         ADW_CTRL_REG_DPE_INTR           0x4000
97 #define         ADW_CTRL_REG_POWER_DONE         0x8000
98 #define         ADW_CTRL_REG_ANY_INTR           0xFF00
99 #define         ADW_CTRL_REG_CMD_RESET          0x00C6
100 #define         ADW_CTRL_REG_CMD_WR_IO_REG      0x00C5
101 #define         ADW_CTRL_REG_CMD_RD_IO_REG      0x00C4
102 #define         ADW_CTRL_REG_CMD_WR_PCI_CFG     0x00C3
103 #define         ADW_CTRL_REG_CMD_RD_PCI_CFG     0x00C2
104
105 #define ADW_RAM_ADDR                            0x0004
106 #define ADW_RAM_DATA                            0x0006
107
108 #define ADW_RISC_CSR                            0x000A
109 #define         ADW_RISC_CSR_STOP               0x0000
110 #define         ADW_RISC_TEST_COND              0x2000
111 #define         ADW_RISC_CSR_RUN                0x4000
112 #define         ADW_RISC_CSR_SINGLE_STEP        0x8000
113
114 #define ADW_SCSI_CFG0                           0x000C
115 #define         ADW_SCSI_CFG0_TIMER_MODEAB      0xC000  /*
116                                                          * Watchdog, Second,
117                                                          * and Selto timer CFG
118                                                          */
119 #define         ADW_SCSI_CFG0_PARITY_EN         0x2000
120 #define         ADW_SCSI_CFG0_EVEN_PARITY       0x1000
121 #define         ADW_SCSI_CFG0_WD_LONG           0x0800  /*
122                                                          * Watchdog Interval,
123                                                          * 1: 57 min, 0: 13 sec
124                                                          */
125 #define         ADW_SCSI_CFG0_QUEUE_128         0x0400  /*
126                                                          * Queue Size,
127                                                          * 1: 128 byte,
128                                                          * 0: 64 byte
129                                                          */
130 #define         ADW_SCSI_CFG0_PRIM_MODE         0x0100
131 #define         ADW_SCSI_CFG0_SCAM_EN           0x0080
132 #define         ADW_SCSI_CFG0_SEL_TMO_LONG      0x0040  /*
133                                                          * Sel/Resel Timeout,
134                                                          * 1: 400 ms,
135                                                          * 0: 1.6 ms
136                                                          */
137 #define         ADW_SCSI_CFG0_CFRM_ID           0x0020  /* SCAM id sel. */
138 #define         ADW_SCSI_CFG0_OUR_ID_EN         0x0010
139 #define         ADW_SCSI_CFG0_OUR_ID            0x000F
140
141
142 #define ADW_SCSI_CFG1                           0x000E
143 #define         ADW_SCSI_CFG1_BIG_ENDIAN        0x8000
144 #define         ADW_SCSI_CFG1_TERM_POL          0x2000
145 #define         ADW_SCSI_CFG1_SLEW_RATE         0x1000
146 #define         ADW_SCSI_CFG1_FILTER_MASK       0x0C00
147 #define         ADW_SCSI_CFG1_FLTR_DISABLE      0x0000
148 #define         ADW_SCSI_CFG1_FLTR_11_TO_20NS   0x0800
149 #define         ADW_SCSI_CFG1_FLTR_21_TO_39NS   0x0C00
150 #define         ADW_SCSI_CFG1_DIS_ACTIVE_NEG    0x0200
151 #define         ADW_SCSI_CFG1_DIFF_MODE         0x0100
152 #define         ADW_SCSI_CFG1_DIFF_SENSE        0x0080
153 #define         ADW_SCSI_CFG1_TERM_CTL_MANUAL   0x0040  /* Global Term Switch */
154 #define         ADW_SCSI_CFG1_TERM_CTL_MASK     0x0030
155 #define         ADW_SCSI_CFG1_TERM_CTL_H        0x0020  /* Enable SCSI-H */
156 #define         ADW_SCSI_CFG1_TERM_CTL_L        0x0010  /* Enable SCSI-L */
157 #define         ADW_SCSI_CFG1_CABLE_DETECT      0x000F
158 #define         ADW_SCSI_CFG1_EXT16_MASK        0x0008  /* Ext16 cable pres */
159 #define         ADW_SCSI_CFG1_EXT8_MASK         0x0004  /* Ext8 cable pres */
160 #define         ADW_SCSI_CFG1_INT8_MASK         0x0002  /* Int8 cable pres */
161 #define         ADW_SCSI_CFG1_INT16_MASK        0x0001  /* Int16 cable pres */
162 #define         ADW_SCSI_CFG1_ILLEGAL_CABLE_CONF_A_MASK \
163 (ADW_SCSI_CFG1_EXT16_MASK|ADW_SCSI_CFG1_INT8_MASK|ADW_SCSI_CFG1_INT16_MASK)
164 #define         ADW_SCSI_CFG1_ILLEGAL_CABLE_CONF_B_MASK \
165 (ADW_SCSI_CFG1_EXT8_MASK|ADW_SCSI_CFG1_INT8_MASK|ADW_SCSI_CFG1_INT16_MASK)
166
167 #define ADW_MEM_CFG                             0x0010
168 #define         ADW_MEM_CFG_BIOS_EN             0x40
169 #define         ADW_MEM_CFG_FAST_EE_CLK         0x20    /* Diagnostic Bit */
170 #define         ADW_MEM_CFG_RAM_SZ_MASK         0x1C    /* RISC RAM Size */
171 #define         ADW_MEM_CFG_RAM_SZ_2KB          0x00
172 #define         ADW_MEM_CFG_RAM_SZ_4KB          0x04
173 #define         ADW_MEM_CFG_RAM_SZ_8KB          0x08
174 #define         ADW_MEM_CFG_RAM_SZ_16KB         0x0C
175 #define         ADW_MEM_CFG_RAM_SZ_32KB         0x10
176 #define         ADW_MEM_CFG_RAM_SZ_64KB         0x14
177
178 #define ADW_EEP_CMD                             0x001A
179 #define         ADW_EEP_CMD_READ                0x0080  /* or in address */
180 #define         ADW_EEP_CMD_WRITE               0x0040  /* or in address */
181 #define         ADW_EEP_CMD_WRITE_ABLE          0x0030
182 #define         ADW_EEP_CMD_WRITE_DISABLE       0x0000
183 #define         ADW_EEP_CMD_DONE                0x0200
184 #define         ADW_EEP_CMD_DONE_ERR            0x0001
185 #define         ADW_EEP_DELAY_MS                100
186
187 #define ADW_EEP_DATA                            0x001C
188
189 #define ADW_DMA_CFG0                            0x0020
190 #define         ADW_DMA_CFG0_BC_THRESH_ENB      0x80
191 #define         ADW_DMA_CFG0_FIFO_THRESH        0x70
192 #define         ADW_DMA_CFG0_FIFO_THRESH_16B    0x00
193 #define         ADW_DMA_CFG0_FIFO_THRESH_32B    0x20
194 #define         ADW_DMA_CFG0_IFO_THRESH_48B     0x30
195 #define         ADW_DMA_CFG0_IFO_THRESH_64B     0x40
196 #define         ADW_DMA_CFG0_IFO_THRESH_80B     0x50
197 #define         ADW_DMA_CFG0_IFO_THRESH_96B     0x60
198 #define         ADW_DMA_CFG0_IFO_THRESH_112B    0x70
199 #define         ADW_DMA_CFG0_START_CTL_MASK     0x0C
200 #define         ADW_DMA_CFG0_START_CTL_TH       0x00 /* Start on thresh */
201 #define         ADW_DMA_CFG0_START_CTL_IDLE     0x04 /* Start when idle */
202 #define         ADW_DMA_CFG0_START_CTL_TH_IDLE  0x08 /* Either */
203 #define         ADW_DMA_CFG0_START_CTL_EM_FU    0x0C /* Start on full/empty */
204 #define         ADW_DMA_CFG0_READ_CMD_MASK      0x03
205 #define         ADW_DMA_CFG0_READ_CMD_MR        0x00
206 #define         ADW_DMA_CFG0_READ_CMD_MRL       0x02
207 #define         ADW_DMA_CFG0_READ_CMD_MRM       0x03
208
209 /* Program Counter */
210 #define ADW_PC                                  0x2A
211
212 #define ADW_SCSI_CTRL                           0x0034
213 #define         ADW_SCSI_CTRL_RSTOUT            0x2000
214
215 #define ADW_SCSI_RESET_HOLD_TIME_US             60
216
217 /* LRAM Constants */
218 #define ADW_CONDOR_MEMSIZE      0x2000 /* 8 KB Internal Memory */
219 #define ADW_MC_BIOSMEM          0x0040 /* BIOS RISC Memory Start */
220 #define ADW_MC_BIOSLEN          0x0050 /* BIOS RISC Memory Length */
221
222 /* ====================== SCSI Request Structures =========================== */
223
224 #define ADW_NO_OF_SG_PER_BLOCK  15
225
226 /*
227  * Although the adapter can deal with S/G lists of indefinite size,
228  * we limit the list to 30 to conserve space as the kernel can only send
229  * us buffers of at most 64KB currently.
230  */
231 #define ADW_SG_BLOCKCNT         2
232 #define ADW_SGSIZE              (ADW_NO_OF_SG_PER_BLOCK * ADW_SG_BLOCKCNT)
233
234 struct adw_sg_elm {
235         u_int32_t sg_addr;
236         u_int32_t sg_count;
237 };
238
239 /* sg block structure used by the microcode */
240 struct adw_sg_block {   
241         u_int8_t  reserved1;
242         u_int8_t  reserved2;
243         u_int8_t  first_entry_no;  /* starting entry number */
244         u_int8_t  last_entry_no;   /* last entry number */
245         u_int32_t sg_busaddr_next; /* link to the next sg block */
246         struct    adw_sg_elm sg_list[ADW_NO_OF_SG_PER_BLOCK];
247 };
248
249 /* Structure representing a single allocation block of adw sg blocks */
250 struct sg_map_node {
251         bus_dmamap_t             sg_dmamap;
252         bus_addr_t               sg_physaddr;
253         struct adw_sg_block*     sg_vaddr;
254         SLIST_ENTRY(sg_map_node) links;
255 };
256
257 typedef enum {
258         QHSTA_NO_ERROR              = 0x00,
259         QHSTA_M_SEL_TIMEOUT         = 0x11,
260         QHSTA_M_DATA_OVER_RUN       = 0x12,
261         QHSTA_M_UNEXPECTED_BUS_FREE = 0x13,
262         QHSTA_M_QUEUE_ABORTED       = 0x15,
263         QHSTA_M_SXFR_SDMA_ERR       = 0x16, /* SCSI DMA Error */
264         QHSTA_M_SXFR_SXFR_PERR      = 0x17, /* SCSI Bus Parity Error */
265         QHSTA_M_RDMA_PERR           = 0x18, /* RISC PCI DMA parity error */
266         QHSTA_M_SXFR_OFF_UFLW       = 0x19, /* Offset Underflow */
267         QHSTA_M_SXFR_OFF_OFLW       = 0x20, /* Offset Overflow */
268         QHSTA_M_SXFR_WD_TMO         = 0x21, /* Watchdog Timeout */
269         QHSTA_M_SXFR_DESELECTED     = 0x22, /* Deselected */
270         QHSTA_M_SXFR_XFR_PH_ERR     = 0x24, /* Transfer Phase Error */
271         QHSTA_M_SXFR_UNKNOWN_ERROR  = 0x25, /* SXFR_STATUS Unknown Error */
272         QHSTA_M_WTM_TIMEOUT         = 0x41,
273         QHSTA_M_BAD_CMPL_STATUS_IN  = 0x42,
274         QHSTA_M_NO_AUTO_REQ_SENSE   = 0x43,
275         QHSTA_M_AUTO_REQ_SENSE_FAIL = 0x44,
276         QHSTA_M_INVALID_DEVICE      = 0x45 /* Bad target ID */
277 } host_status_t;
278
279 typedef enum {
280         QD_NO_STATUS       = 0x00, /* Request not completed yet. */
281         QD_NO_ERROR        = 0x01,
282         QD_ABORTED_BY_HOST = 0x02,
283         QD_WITH_ERROR      = 0x04
284 } done_status_t;
285
286 /*
287  * Microcode request structure
288  *
289  * All fields in this structure are used by the microcode so their
290  * size and ordering cannot be changed.
291  */
292 struct adw_scsi_req_q {
293         u_int8_t  cntl;           /* Ucode flags and state. */
294         u_int8_t  sg_entry_cnt;   /* SG element count. Zero for no SG. */
295         u_int8_t  target_id;      /* Device target identifier. */
296         u_int8_t  target_lun;     /* Device target logical unit number. */
297         u_int32_t data_addr;      /* Data buffer physical address. */
298         u_int32_t data_cnt;       /* Data count. Ucode sets to residual. */
299         u_int32_t sense_addr;     /* Sense buffer physical address. */
300         u_int32_t srb_ptr;        /* Driver request pointer. */
301         u_int8_t  a_flag;         /* Adv Library flag field. */
302         u_int8_t  sense_len;      /* Auto-sense length. Residual on complete. */
303         u_int8_t  cdb_len;        /* SCSI CDB length. */
304         u_int8_t  tag_code;       /* SCSI-2 Tag Queue Code: 00, 20-22. */
305         u_int8_t  done_status;    /* Completion status. */
306         u_int8_t  scsi_status;    /* SCSI status byte. */
307         u_int8_t  host_status;    /* Ucode host status. */
308
309         u_int8_t  ux_sg_ix;       /* Ucode working SG variable. */
310         u_int8_t  cdb[12];        /* SCSI command block. */
311         u_int32_t sg_real_addr;   /* SG list physical address. */ 
312         u_int32_t free_scsiq_link;/* Unused */
313         u_int32_t ux_wk_data_cnt; /* Saved data count at disconnection. */
314         u_int32_t scsi_req_baddr; /* Bus address of this request. */
315         u_int32_t sg_block_index; /* sg_block tag (Unused) */
316 };
317
318 typedef enum {
319         ACB_FREE                = 0x00,
320         ACB_ACTIVE              = 0x01,
321         ACB_RELEASE_SIMQ        = 0x02
322 } acb_state;
323
324 struct acb {
325         struct          adw_scsi_req_q queue;
326         bus_dmamap_t    dmamap;
327         acb_state       state;
328         union           ccb *ccb;
329         struct          adw_sg_block* sg_blocks;
330         bus_addr_t      sg_busaddr;
331         struct          scsi_sense_data sense_data;
332         SLIST_ENTRY(acb) links;
333 };
334
335 typedef struct {
336         u_int16_t bios_init_dis    :1,/* don't act as initiator. */
337                   bios_ext_trans   :1,/* > 1 GB support */
338                   bios_more_2disk  :1,/* > 2 Disk Support */
339                   bios_no_removable:1,/* don't support removables */
340                   bios_cd_boot     :1,/* support bootable CD */
341                                    :1,
342                   bios_multi_lun   :1,/* support multiple LUNs */
343                   bios_message     :1,/* display BIOS message */
344                                    :1,
345                   bios_reset_sb    :1,/* Reset SCSI bus during init. */
346                                    :1,
347                   bios_quiet       :1,/* No verbose initialization. */
348                   bios_scsi_par_en :1,/* SCSI parity enabled */
349                                    :3;
350 } adw_bios_ctrl;
351
352 /*
353  * EEPROM configuration format
354  *
355  * Field naming convention: 
356  *
357  *  *_enable indicates the field enables or disables the feature. The
358  *  value is never reset.
359  *
360  *  *_able indicates both whether a feature should be enabled or disabled
361  *  and whether a device is capable of the feature. At initialization
362  *  this field may be set, but later if a device is found to be incapable
363  *  of the feature, the field is cleared.
364  *
365  * Default values are maintained in a_init.c in the structure
366  * Default_EEPROM_Config.
367  */
368 struct adw_eeprom
369 {                              
370         u_int16_t cfg_lsw;      /* 00 power up initialization */
371 #define         ADW_EEPROM_BIG_ENDIAN   0x8000
372 #define         ADW_EEPROM_BIOS_ENABLE  0x4000
373 #define         ADW_EEPROM_TERM_POL     0x2000
374
375                                 /* bit 13 set - Term Polarity Control */
376                                 /* bit 14 set - BIOS Enable */
377                                 /* bit 15 set - Big Endian Mode */
378         u_int16_t cfg_msw;      /* unused */
379         u_int16_t disc_enable;
380         u_int16_t wdtr_able;
381         u_int16_t sdtr_able;
382         u_int16_t start_motor;
383         u_int16_t tagqng_able;
384         u_int16_t bios_scan;
385         u_int16_t scam_tolerant;
386  
387         u_int8_t  adapter_scsi_id;
388         u_int8_t  bios_boot_delay;
389  
390         u_int8_t  scsi_reset_delay;
391         u_int8_t  bios_id_lun;  /*    high nibble is lun */  
392                                 /*    low nibble is scsi id */
393
394         u_int8_t  termination;  /* 0 - automatic */
395 #define         ADW_EEPROM_TERM_AUTO            0
396 #define         ADW_EEPROM_TERM_OFF             1
397 #define         ADW_EEPROM_TERM_HIGH_ON         2
398 #define         ADW_EEPROM_TERM_BOTH_ON         3
399
400         u_int8_t  reserved1;    /*    reserved byte (not used) */                                  
401         adw_bios_ctrl bios_ctrl;
402
403         u_int16_t ultra_able;   /* 13 ULTRA speed able */ 
404         u_int16_t reserved2;    /* 14 reserved */
405         u_int8_t  max_host_qng; /* 15 maximum host queuing */
406         u_int8_t  max_dvc_qng;  /*    maximum per device queuing */
407         u_int16_t dvc_cntl;     /* 16 control bit for driver */
408         u_int16_t bug_fix;      /* 17 control bit for bug fix */
409         u_int16_t serial_number[3];
410         u_int16_t checksum;
411         u_int8_t  oem_name[16];
412         u_int16_t dvc_err_code;
413         u_int16_t adv_err_code;
414         u_int16_t adv_err_addr;
415         u_int16_t saved_dvc_err_code;
416         u_int16_t saved_adv_err_code;
417         u_int16_t saved_adv_err_addr;
418         u_int16_t num_of_err;
419 };
420
421 /* EEProm Addresses */
422 #define ADW_EEP_DVC_CFG_BEGIN           0x00
423 #define ADW_EEP_DVC_CFG_END     (offsetof(struct adw_eeprom, checksum)/2)
424 #define ADW_EEP_DVC_CTL_BEGIN   (offsetof(struct adw_eeprom, oem_name)/2)
425 #define ADW_EEP_MAX_WORD_ADDR   (sizeof(struct adw_eeprom)/2)
426
427 typedef enum {
428         ADW_STATE_NORMAL        = 0x00,
429         ADW_RESOURCE_SHORTAGE   = 0x01
430 } adw_state;
431
432 struct adw_softc
433 {
434         bus_space_tag_t           tag;
435         bus_space_handle_t        bsh;
436         adw_state                 state;
437         bus_dma_tag_t             buffer_dmat;
438         struct acb               *acbs;
439         LIST_HEAD(, ccb_hdr)      pending_ccbs;
440         SLIST_HEAD(, acb)         free_acb_list;
441         bus_dma_tag_t             parent_dmat;
442         bus_dma_tag_t             acb_dmat;     /* dmat for our ccb array */
443         bus_dmamap_t              acb_dmamap;
444         bus_dma_tag_t             sg_dmat;      /* dmat for our sg maps */
445         SLIST_HEAD(, sg_map_node) sg_maps;
446         bus_addr_t                acb_busbase;
447         struct cam_path          *path;
448         struct cam_sim           *sim;
449         u_int                     max_acbs;
450         u_int                     num_acbs;
451         u_int                     initiator_id;
452         u_int                     init_level;
453         u_int                     unit;
454         char*                     name;
455         cam_status                last_reset;   /* Last reset type */
456         adw_bios_ctrl             bios_ctrl;
457         adw_idle_cmd_t            idle_cmd;
458         u_int                     idle_cmd_param;
459         volatile int              idle_command_cmp;
460         u_int16_t                 user_wdtr;
461         u_int16_t                 user_sdtr;
462         u_int16_t                 user_ultra;
463         u_int16_t                 user_tagenb;
464         u_int16_t                 tagenb;
465         u_int16_t                 user_discenb;
466         u_int16_t                 serial_number[3];
467 };
468
469 extern struct adw_eeprom adw_default_eeprom;
470
471 #define adw_inb(adw, port)                              \
472         bus_space_read_1((adw)->tag, (adw)->bsh, port)
473 #define adw_inw(adw, port)                              \
474         bus_space_read_2((adw)->tag, (adw)->bsh, port)
475 #define adw_inl(adw, port)                              \
476         bus_space_read_4((adw)->tag, (adw)->bsh, port)
477
478 #define adw_outb(adw, port, value)                      \
479         bus_space_write_1((adw)->tag, (adw)->bsh, port, value)
480 #define adw_outw(adw, port, value)                      \
481         bus_space_write_2((adw)->tag, (adw)->bsh, port, value)
482 #define adw_outl(adw, port, value)                      \
483         bus_space_write_4((adw)->tag, (adw)->bsh, port, value)
484
485 static __inline const char*     adw_name(struct adw_softc *adw);
486 static __inline u_int   adw_lram_read_8(struct adw_softc *adw, u_int addr);
487 static __inline u_int   adw_lram_read_16(struct adw_softc *adw, u_int addr);
488 static __inline u_int   adw_lram_read_32(struct adw_softc *adw, u_int addr);
489 static __inline void    adw_lram_write_8(struct adw_softc *adw, u_int addr,
490                                          u_int value);
491 static __inline void    adw_lram_write_16(struct adw_softc *adw, u_int addr,
492                                           u_int value);
493 static __inline void    adw_lram_write_32(struct adw_softc *adw, u_int addr,
494                                           u_int value);
495
496 static __inline const char*
497 adw_name(struct adw_softc *adw)
498 {
499         return (adw->name);
500 }
501
502 static __inline u_int
503 adw_lram_read_8(struct adw_softc *adw, u_int addr)
504 {
505         adw_outw(adw, ADW_RAM_ADDR, addr);
506         return (adw_inb(adw, ADW_RAM_DATA));
507 }
508
509 static __inline u_int
510 adw_lram_read_16(struct adw_softc *adw, u_int addr)
511 {
512         adw_outw(adw, ADW_RAM_ADDR, addr);
513         return (adw_inw(adw, ADW_RAM_DATA));
514 }
515
516 static __inline u_int
517 adw_lram_read_32(struct adw_softc *adw, u_int addr)
518 {
519         u_int retval;
520
521         adw_outw(adw, ADW_RAM_ADDR, addr);
522         retval = adw_inw(adw, ADW_RAM_DATA);
523         retval |= (adw_inw(adw, ADW_RAM_DATA) << 16);
524         return (retval);
525 }
526
527 static __inline void
528 adw_lram_write_8(struct adw_softc *adw, u_int addr, u_int value)
529 {
530         adw_outw(adw, ADW_RAM_ADDR, addr);
531         adw_outb(adw, ADW_RAM_DATA, value);
532 }
533
534 static __inline void
535 adw_lram_write_16(struct adw_softc *adw, u_int addr, u_int value)
536 {
537         adw_outw(adw, ADW_RAM_ADDR, addr);
538         adw_outw(adw, ADW_RAM_DATA, value);
539 }
540
541 static __inline void
542 adw_lram_write_32(struct adw_softc *adw, u_int addr, u_int value)
543 {
544         adw_outw(adw, ADW_RAM_ADDR, addr);
545         adw_outw(adw, ADW_RAM_DATA, value);
546         adw_outw(adw, ADW_RAM_DATA, value >> 16);
547 }
548
549 /* Intialization */
550 int             adw_find_signature(bus_space_tag_t tag, bus_space_handle_t bsh);
551 void            adw_reset_chip(struct adw_softc *adw);
552 u_int16_t       adw_eeprom_read(struct adw_softc *adw, struct adw_eeprom *buf);
553 void            adw_eeprom_write(struct adw_softc *adw, struct adw_eeprom *buf);
554 int             adw_init_chip(struct adw_softc *adw, u_int term_scsicfg1);
555
556 /* Idle Commands */
557 void                    adw_idle_cmd_send(struct adw_softc *adw, u_int cmd,
558                                           u_int parameter);
559 adw_idle_cmd_status_t   adw_idle_cmd_wait(struct adw_softc *adw);
560
561 /* SCSI Transaction Processing */
562 static __inline void    adw_send_acb(struct adw_softc *adw, struct acb *acb,
563                                      u_int32_t acb_baddr);
564
565 static __inline void
566 adw_send_acb(struct adw_softc *adw, struct acb *acb, u_int32_t acb_baddr)
567 {
568         u_int next_queue;
569
570         /* Determine the next free queue. */
571         next_queue = adw_lram_read_8(adw, ADW_MC_HOST_NEXT_READY);
572         next_queue = ADW_MC_RISC_Q_LIST_BASE
573                    + (next_queue * ADW_MC_RISC_Q_LIST_SIZE);
574
575         /*
576          * Write the physical address of the host Q to the free Q.
577          */
578         adw_lram_write_32(adw, next_queue + RQL_PHYADDR, acb_baddr);
579
580         adw_lram_write_8(adw, next_queue + RQL_TID, acb->queue.target_id);
581
582         /*
583          * Set the ADW_MC_HOST_NEXT_READY (0x128) microcode variable to
584          * the 'next_queue' request forward pointer.
585          *
586          * Do this *before* changing the 'next_queue' queue to QS_READY.
587          * After the state is changed to QS_READY 'RQL_FWD' will be changed
588          * by the microcode.
589          *
590          */
591         adw_lram_write_8(adw, ADW_MC_HOST_NEXT_READY,
592                          adw_lram_read_8(adw, next_queue + RQL_FWD));
593
594         /*
595          * Change the state of 'next_queue' request from QS_FREE to
596          * QS_READY which will cause the microcode to pick it up and
597          * execute it.
598          *  
599          * Can't reference 'next_queue' after changing the request
600          * state to QS_READY. The microcode now owns the request.
601          */
602         adw_lram_write_8(adw, next_queue + RQL_STATE, ADW_MC_QS_READY);
603 }
604      
605 #endif /* _ADWLIB_H_ */