Merge from vendor branch GCC:
[dragonfly.git] / sys / dev / disk / advansys / advlib.c
1 /*
2  * Low level routines for the Advanced Systems Inc. SCSI controllers chips
3  *
4  * Copyright (c) 1996-1997, 1999-2000 Justin Gibbs.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions, and the following disclaimer,
12  *    without modification, immediately at the beginning of the file.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. The name of the author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
23  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  *
31  * $FreeBSD: src/sys/dev/advansys/advlib.c,v 1.15.2.1 2000/04/14 13:32:49 nyan Exp $
32  * $DragonFly: src/sys/dev/disk/advansys/advlib.c,v 1.6 2005/06/03 16:57:12 eirikn Exp $
33  */
34 /*
35  * Ported from:
36  * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
37  *     
38  * Copyright (c) 1995-1996 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 #include <sys/param.h>
48 #include <sys/kernel.h>
49 #include <sys/systm.h>
50 #include <sys/thread2.h>
51
52 #include <machine/bus_pio.h>
53 #include <machine/bus.h>
54 #include <machine/clock.h>
55 #include <machine/resource.h>
56 #include <sys/bus.h> 
57 #include <sys/rman.h> 
58
59 #include <bus/cam/cam.h>
60 #include <bus/cam/cam_ccb.h>
61 #include <bus/cam/cam_sim.h>
62 #include <bus/cam/cam_xpt_sim.h>
63
64 #include <bus/cam/scsi/scsi_all.h>
65 #include <bus/cam/scsi/scsi_message.h>
66 #include <bus/cam/scsi/scsi_da.h>
67 #include <bus/cam/scsi/scsi_cd.h>
68
69 #include <vm/vm.h>
70 #include <vm/vm_param.h>
71 #include <vm/pmap.h>
72
73 #include "advansys.h"
74 #include "advmcode.h"
75
76 struct adv_quirk_entry {
77         struct scsi_inquiry_pattern inq_pat;
78         u_int8_t quirks;
79 #define ADV_QUIRK_FIX_ASYN_XFER_ALWAYS  0x01
80 #define ADV_QUIRK_FIX_ASYN_XFER         0x02
81 };
82
83 static struct adv_quirk_entry adv_quirk_table[] =
84 {
85         {
86                 { T_CDROM, SIP_MEDIA_REMOVABLE, "HP", "*", "*" },
87                 ADV_QUIRK_FIX_ASYN_XFER_ALWAYS|ADV_QUIRK_FIX_ASYN_XFER
88         },
89         {
90                 { T_CDROM, SIP_MEDIA_REMOVABLE, "NEC", "CD-ROM DRIVE", "*" },
91                 0
92         },
93         {
94                 {
95                   T_SEQUENTIAL, SIP_MEDIA_REMOVABLE,
96                   "TANDBERG", " TDC 36", "*"
97                 },
98                 0
99         },
100         {
101                 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "WANGTEK", "*", "*" },
102                 0
103         },
104         {
105                 {
106                   T_PROCESSOR, SIP_MEDIA_REMOVABLE|SIP_MEDIA_FIXED,
107                   "*", "*", "*"
108                 },
109                 0
110         },
111         {
112                 {
113                   T_SCANNER, SIP_MEDIA_REMOVABLE|SIP_MEDIA_FIXED,
114                   "*", "*", "*"
115                 },
116                 0
117         },
118         {
119                 /* Default quirk entry */
120                 {
121                   T_ANY, SIP_MEDIA_REMOVABLE|SIP_MEDIA_FIXED,
122                   /*vendor*/"*", /*product*/"*", /*revision*/"*"
123                 }, 
124                 ADV_QUIRK_FIX_ASYN_XFER,
125         }
126 };
127
128 /*
129  * Allowable periods in ns
130  */
131 static u_int8_t adv_sdtr_period_tbl[] =
132 {
133         25,
134         30,
135         35,
136         40,
137         50,
138         60,
139         70,
140         85
141 };
142
143 static u_int8_t adv_sdtr_period_tbl_ultra[] =
144 {
145         12,
146         19,
147         25,
148         32,
149         38,
150         44,
151         50,
152         57,
153         63,
154         69,
155         75,
156         82,
157         88, 
158         94,
159         100,
160         107
161 };
162
163 struct ext_msg {
164         u_int8_t msg_type;
165         u_int8_t msg_len;
166         u_int8_t msg_req;
167         union {
168                 struct {
169                         u_int8_t sdtr_xfer_period;
170                         u_int8_t sdtr_req_ack_offset;
171                 } sdtr;
172                 struct {
173                         u_int8_t wdtr_width;
174                 } wdtr;
175                 struct {
176                         u_int8_t mdp[4];
177                 } mdp;
178         } u_ext_msg;
179         u_int8_t res;
180 };
181
182 #define xfer_period     u_ext_msg.sdtr.sdtr_xfer_period
183 #define req_ack_offset  u_ext_msg.sdtr.sdtr_req_ack_offset
184 #define wdtr_width      u_ext_msg.wdtr.wdtr_width
185 #define mdp_b3          u_ext_msg.mdp_b3
186 #define mdp_b2          u_ext_msg.mdp_b2
187 #define mdp_b1          u_ext_msg.mdp_b1
188 #define mdp_b0          u_ext_msg.mdp_b0
189
190 /*
191  * Some of the early PCI adapters have problems with
192  * async transfers.  Instead use an offset of 1.
193  */
194 #define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
195
196 /* LRAM routines */
197 static void      adv_read_lram_16_multi(struct adv_softc *adv, u_int16_t s_addr,
198                                         u_int16_t *buffer, int count);
199 static void      adv_write_lram_16_multi(struct adv_softc *adv,
200                                          u_int16_t s_addr, u_int16_t *buffer,
201                                          int count);
202 static void      adv_mset_lram_16(struct adv_softc *adv, u_int16_t s_addr,
203                                   u_int16_t set_value, int count);
204 static u_int32_t adv_msum_lram_16(struct adv_softc *adv, u_int16_t s_addr,
205                                   int count);
206
207 static int       adv_write_and_verify_lram_16(struct adv_softc *adv,
208                                               u_int16_t addr, u_int16_t value);
209 static u_int32_t adv_read_lram_32(struct adv_softc *adv, u_int16_t addr);
210
211
212 static void      adv_write_lram_32(struct adv_softc *adv, u_int16_t addr,
213                                    u_int32_t value);
214 static void      adv_write_lram_32_multi(struct adv_softc *adv,
215                                          u_int16_t s_addr, u_int32_t *buffer,
216                                          int count);
217
218 /* EEPROM routines */
219 static u_int16_t adv_read_eeprom_16(struct adv_softc *adv, u_int8_t addr);
220 static u_int16_t adv_write_eeprom_16(struct adv_softc *adv, u_int8_t addr,
221                                      u_int16_t value);
222 static int       adv_write_eeprom_cmd_reg(struct adv_softc *adv,
223                                           u_int8_t cmd_reg);
224 static int       adv_set_eeprom_config_once(struct adv_softc *adv,
225                                             struct adv_eeprom_config *eeconfig);
226
227 /* Initialization */
228 static u_int32_t adv_load_microcode(struct adv_softc *adv, u_int16_t s_addr,
229                                     u_int16_t *mcode_buf, u_int16_t mcode_size);
230
231 static void      adv_reinit_lram(struct adv_softc *adv);
232 static void      adv_init_lram(struct adv_softc *adv);
233 static int       adv_init_microcode_var(struct adv_softc *adv);
234 static void      adv_init_qlink_var(struct adv_softc *adv);
235
236 /* Interrupts */
237 static void      adv_disable_interrupt(struct adv_softc *adv);
238 static void      adv_enable_interrupt(struct adv_softc *adv);
239 static void      adv_toggle_irq_act(struct adv_softc *adv);
240
241 /* Chip Control */
242 static int       adv_host_req_chip_halt(struct adv_softc *adv);
243 static void      adv_set_chip_ih(struct adv_softc *adv, u_int16_t ins_code);
244 #if UNUSED
245 static u_int8_t  adv_get_chip_scsi_ctrl(struct adv_softc *adv);
246 #endif
247
248 /* Queue handling and execution */
249 static __inline int
250                  adv_sgcount_to_qcount(int sgcount);
251
252 static __inline int
253 adv_sgcount_to_qcount(int sgcount)
254 {
255         int     n_sg_list_qs;
256
257         n_sg_list_qs = ((sgcount - 1) / ADV_SG_LIST_PER_Q);
258         if (((sgcount - 1) % ADV_SG_LIST_PER_Q) != 0)
259                 n_sg_list_qs++;
260         return (n_sg_list_qs + 1);
261 }
262
263 static void      adv_get_q_info(struct adv_softc *adv, u_int16_t s_addr,
264                                 u_int16_t *inbuf, int words);
265 static u_int     adv_get_num_free_queues(struct adv_softc *adv, u_int8_t n_qs);
266 static u_int8_t  adv_alloc_free_queues(struct adv_softc *adv,
267                                        u_int8_t free_q_head, u_int8_t n_free_q);
268 static u_int8_t  adv_alloc_free_queue(struct adv_softc *adv,
269                                       u_int8_t free_q_head);
270 static int       adv_send_scsi_queue(struct adv_softc *adv,
271                                      struct adv_scsi_q *scsiq,
272                                      u_int8_t n_q_required);
273 static void      adv_put_ready_sg_list_queue(struct adv_softc *adv,
274                                              struct adv_scsi_q *scsiq,
275                                              u_int q_no);
276 static void      adv_put_ready_queue(struct adv_softc *adv,
277                                      struct adv_scsi_q *scsiq, u_int q_no);
278 static void      adv_put_scsiq(struct adv_softc *adv, u_int16_t s_addr,
279                                u_int16_t *buffer, int words);
280
281 /* Messages */
282 static void      adv_handle_extmsg_in(struct adv_softc *adv,
283                                       u_int16_t halt_q_addr, u_int8_t q_cntl,
284                                       target_bit_vector target_id,
285                                       int tid);
286 static void      adv_msgout_sdtr(struct adv_softc *adv, u_int8_t sdtr_period,
287                                  u_int8_t sdtr_offset);
288 static void      adv_set_sdtr_reg_at_id(struct adv_softc *adv, int id,
289                                         u_int8_t sdtr_data);
290
291
292 /* Exported functions first */
293
294 void
295 advasync(void *callback_arg, u_int32_t code, struct cam_path *path, void *arg)
296 {
297         struct adv_softc *adv;
298
299         adv = (struct adv_softc *)callback_arg;
300         switch (code) {
301         case AC_FOUND_DEVICE:
302         {
303                 struct ccb_getdev *cgd;
304                 target_bit_vector target_mask;
305                 int num_entries;
306                 caddr_t match;
307                 struct adv_quirk_entry *entry;
308                 struct adv_target_transinfo* tinfo;
309  
310                 cgd = (struct ccb_getdev *)arg;
311
312                 target_mask = ADV_TID_TO_TARGET_MASK(cgd->ccb_h.target_id);
313
314                 num_entries = sizeof(adv_quirk_table)/sizeof(*adv_quirk_table);
315                 match = cam_quirkmatch((caddr_t)&cgd->inq_data,
316                                        (caddr_t)adv_quirk_table,
317                                        num_entries, sizeof(*adv_quirk_table),
318                                        scsi_inquiry_match);
319         
320                 if (match == NULL)
321                         panic("advasync: device didn't match wildcard entry!!");
322
323                 entry = (struct adv_quirk_entry *)match;
324
325                 if (adv->bug_fix_control & ADV_BUG_FIX_ASYN_USE_SYN) {
326                         if ((entry->quirks & ADV_QUIRK_FIX_ASYN_XFER_ALWAYS)!=0)
327                                 adv->fix_asyn_xfer_always |= target_mask;
328                         else
329                                 adv->fix_asyn_xfer_always &= ~target_mask;
330                         /*
331                          * We start out life with all bits set and clear them
332                          * after we've determined that the fix isn't necessary.
333                          * It may well be that we've already cleared a target
334                          * before the full inquiry session completes, so don't
335                          * gratuitously set a target bit even if it has this
336                          * quirk.  But, if the quirk exonerates a device, clear
337                          * the bit now.
338                          */
339                         if ((entry->quirks & ADV_QUIRK_FIX_ASYN_XFER) == 0)
340                                 adv->fix_asyn_xfer &= ~target_mask;
341                 }
342                 /*
343                  * Reset our sync settings now that we've determined
344                  * what quirks are in effect for the device.
345                  */
346                 tinfo = &adv->tinfo[cgd->ccb_h.target_id];
347                 adv_set_syncrate(adv, cgd->ccb_h.path,
348                                  cgd->ccb_h.target_id,
349                                  tinfo->current.period,
350                                  tinfo->current.offset,
351                                  ADV_TRANS_CUR);
352                 break;
353         }
354         case AC_LOST_DEVICE:
355         {
356                 u_int target_mask;
357
358                 if (adv->bug_fix_control & ADV_BUG_FIX_ASYN_USE_SYN) {
359                         target_mask = 0x01 << xpt_path_target_id(path);
360                         adv->fix_asyn_xfer |= target_mask;
361                 }
362
363                 /*
364                  * Revert to async transfers
365                  * for the next device.
366                  */
367                 adv_set_syncrate(adv, /*path*/NULL,
368                                  xpt_path_target_id(path),
369                                  /*period*/0,
370                                  /*offset*/0,
371                                  ADV_TRANS_GOAL|ADV_TRANS_CUR);
372         }
373         default:
374                 break;
375         }
376 }
377
378 void
379 adv_set_bank(struct adv_softc *adv, u_int8_t bank)
380 {
381         u_int8_t control;
382
383         /*
384          * Start out with the bank reset to 0
385          */
386         control = ADV_INB(adv, ADV_CHIP_CTRL)
387                   &  (~(ADV_CC_SINGLE_STEP | ADV_CC_TEST
388                         | ADV_CC_DIAG | ADV_CC_SCSI_RESET
389                         | ADV_CC_CHIP_RESET | ADV_CC_BANK_ONE));
390         if (bank == 1) {
391                 control |= ADV_CC_BANK_ONE;
392         } else if (bank == 2) {
393                 control |= ADV_CC_DIAG | ADV_CC_BANK_ONE;
394         }
395         ADV_OUTB(adv, ADV_CHIP_CTRL, control);
396 }
397
398 u_int8_t
399 adv_read_lram_8(struct adv_softc *adv, u_int16_t addr)
400 {
401         u_int8_t   byte_data;
402         u_int16_t  word_data;
403
404         /*
405          * LRAM is accessed on 16bit boundaries.
406          */
407         ADV_OUTW(adv, ADV_LRAM_ADDR, addr & 0xFFFE);
408         word_data = ADV_INW(adv, ADV_LRAM_DATA);
409         if (addr & 1) {
410 #if BYTE_ORDER == BIG_ENDIAN
411                 byte_data = (u_int8_t)(word_data & 0xFF);
412 #else
413                 byte_data = (u_int8_t)((word_data >> 8) & 0xFF);
414 #endif
415         } else {
416 #if BYTE_ORDER == BIG_ENDIAN
417                 byte_data = (u_int8_t)((word_data >> 8) & 0xFF);
418 #else           
419                 byte_data = (u_int8_t)(word_data & 0xFF);
420 #endif
421         }
422         return (byte_data);
423 }
424
425 void
426 adv_write_lram_8(struct adv_softc *adv, u_int16_t addr, u_int8_t value)
427 {
428         u_int16_t word_data;
429
430         word_data = adv_read_lram_16(adv, addr & 0xFFFE);
431         if (addr & 1) {
432                 word_data &= 0x00FF;
433                 word_data |= (((u_int8_t)value << 8) & 0xFF00);
434         } else {
435                 word_data &= 0xFF00;
436                 word_data |= ((u_int8_t)value & 0x00FF);
437         }
438         adv_write_lram_16(adv, addr & 0xFFFE, word_data);
439 }
440
441
442 u_int16_t
443 adv_read_lram_16(struct adv_softc *adv, u_int16_t addr)
444 {
445         ADV_OUTW(adv, ADV_LRAM_ADDR, addr);
446         return (ADV_INW(adv, ADV_LRAM_DATA));
447 }
448
449 void
450 adv_write_lram_16(struct adv_softc *adv, u_int16_t addr, u_int16_t value)
451 {
452         ADV_OUTW(adv, ADV_LRAM_ADDR, addr);
453         ADV_OUTW(adv, ADV_LRAM_DATA, value);
454 }
455
456 /*
457  * Determine if there is a board at "iobase" by looking
458  * for the AdvanSys signatures.  Return 1 if a board is
459  * found, 0 otherwise.
460  */
461 int                         
462 adv_find_signature(bus_space_tag_t tag, bus_space_handle_t bsh)
463 {                            
464         u_int16_t signature;
465
466         if (bus_space_read_1(tag, bsh, ADV_SIGNATURE_BYTE) == ADV_1000_ID1B) {
467                 signature = bus_space_read_2(tag, bsh, ADV_SIGNATURE_WORD);
468                 if ((signature == ADV_1000_ID0W)
469                  || (signature == ADV_1000_ID0W_FIX))
470                         return (1);
471         }
472         return (0);
473 }
474
475 void
476 adv_lib_init(struct adv_softc *adv)
477 {
478         if ((adv->type & ADV_ULTRA) != 0) {
479                 adv->sdtr_period_tbl = adv_sdtr_period_tbl_ultra;
480                 adv->sdtr_period_tbl_size = sizeof(adv_sdtr_period_tbl_ultra);
481         } else {
482                 adv->sdtr_period_tbl = adv_sdtr_period_tbl;
483                 adv->sdtr_period_tbl_size = sizeof(adv_sdtr_period_tbl);                
484         }
485 }
486
487 u_int16_t
488 adv_get_eeprom_config(struct adv_softc *adv, struct
489                       adv_eeprom_config  *eeprom_config)
490 {
491         u_int16_t       sum;
492         u_int16_t       *wbuf;
493         u_int8_t        cfg_beg;
494         u_int8_t        cfg_end;
495         u_int8_t        s_addr;
496
497         wbuf = (u_int16_t *)eeprom_config;
498         sum = 0;
499
500         for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
501                 *wbuf = adv_read_eeprom_16(adv, s_addr);
502                 sum += *wbuf;
503         }
504
505         if (adv->type & ADV_VL) {
506                 cfg_beg = ADV_EEPROM_CFG_BEG_VL;
507                 cfg_end = ADV_EEPROM_MAX_ADDR_VL;
508         } else {
509                 cfg_beg = ADV_EEPROM_CFG_BEG;
510                 cfg_end = ADV_EEPROM_MAX_ADDR;
511         }
512
513         for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
514                 *wbuf = adv_read_eeprom_16(adv, s_addr);
515                 sum += *wbuf;
516 #if ADV_DEBUG_EEPROM
517                 printf("Addr 0x%x: 0x%04x\n", s_addr, *wbuf);
518 #endif
519         }
520         *wbuf = adv_read_eeprom_16(adv, s_addr);
521         return (sum);
522 }
523
524 int
525 adv_set_eeprom_config(struct adv_softc *adv,
526                       struct adv_eeprom_config *eeprom_config)
527 {
528         int     retry;
529
530         retry = 0;
531         while (1) {
532                 if (adv_set_eeprom_config_once(adv, eeprom_config) == 0) {
533                         break;
534                 }
535                 if (++retry > ADV_EEPROM_MAX_RETRY) {
536                         break;
537                 }
538         }
539         return (retry > ADV_EEPROM_MAX_RETRY);
540 }
541
542 int
543 adv_reset_chip(struct adv_softc *adv, int reset_bus)
544 {
545         adv_stop_chip(adv);
546         ADV_OUTB(adv, ADV_CHIP_CTRL, ADV_CC_CHIP_RESET | ADV_CC_HALT
547                                      | (reset_bus ? ADV_CC_SCSI_RESET : 0));
548         DELAY(60);
549
550         adv_set_chip_ih(adv, ADV_INS_RFLAG_WTM);
551         adv_set_chip_ih(adv, ADV_INS_HALT);
552
553         if (reset_bus)
554                 ADV_OUTB(adv, ADV_CHIP_CTRL, ADV_CC_CHIP_RESET | ADV_CC_HALT);
555
556         ADV_OUTB(adv, ADV_CHIP_CTRL, ADV_CC_HALT);
557         if (reset_bus)
558                 DELAY(200 * 1000);
559
560         ADV_OUTW(adv, ADV_CHIP_STATUS, ADV_CIW_CLR_SCSI_RESET_INT);
561         ADV_OUTW(adv, ADV_CHIP_STATUS, 0);
562         return (adv_is_chip_halted(adv));
563 }
564
565 int
566 adv_test_external_lram(struct adv_softc* adv)
567 {
568         u_int16_t       q_addr;
569         u_int16_t       saved_value;
570         int             success;
571
572         success = 0;
573
574         q_addr = ADV_QNO_TO_QADDR(241);
575         saved_value = adv_read_lram_16(adv, q_addr);
576         if (adv_write_and_verify_lram_16(adv, q_addr, 0x55AA) == 0) {
577                 success = 1;
578                 adv_write_lram_16(adv, q_addr, saved_value);
579         }
580         return (success);
581 }
582
583
584 int
585 adv_init_lram_and_mcode(struct adv_softc *adv)
586 {
587         u_int32_t       retval;
588
589         adv_disable_interrupt(adv);
590
591         adv_init_lram(adv);
592
593         retval = adv_load_microcode(adv, 0, (u_int16_t *)adv_mcode,
594                                     adv_mcode_size);
595         if (retval != adv_mcode_chksum) {
596                 printf("adv%d: Microcode download failed checksum!\n",
597                        adv->unit);
598                 return (1);
599         }
600         
601         if (adv_init_microcode_var(adv) != 0)
602                 return (1);
603
604         adv_enable_interrupt(adv);
605         return (0);
606 }
607
608 u_int8_t
609 adv_get_chip_irq(struct adv_softc *adv)
610 {
611         u_int16_t       cfg_lsw;
612         u_int8_t        chip_irq;
613
614         cfg_lsw = ADV_INW(adv, ADV_CONFIG_LSW);
615
616         if ((adv->type & ADV_VL) != 0) {
617                 chip_irq = (u_int8_t)(((cfg_lsw >> 2) & 0x07));
618                 if ((chip_irq == 0) ||
619                     (chip_irq == 4) ||
620                     (chip_irq == 7)) {
621                         return (0);
622                 }
623                 return (chip_irq + (ADV_MIN_IRQ_NO - 1));
624         }
625         chip_irq = (u_int8_t)(((cfg_lsw >> 2) & 0x03));
626         if (chip_irq == 3)
627                 chip_irq += 2;
628         return (chip_irq + ADV_MIN_IRQ_NO);
629 }
630
631 u_int8_t
632 adv_set_chip_irq(struct adv_softc *adv, u_int8_t irq_no)
633 {
634         u_int16_t       cfg_lsw;
635
636         if ((adv->type & ADV_VL) != 0) {
637                 if (irq_no != 0) {
638                         if ((irq_no < ADV_MIN_IRQ_NO)
639                          || (irq_no > ADV_MAX_IRQ_NO)) {
640                                 irq_no = 0;
641                         } else {
642                                 irq_no -= ADV_MIN_IRQ_NO - 1;
643                         }
644                 }
645                 cfg_lsw = ADV_INW(adv, ADV_CONFIG_LSW) & 0xFFE3;
646                 cfg_lsw |= 0x0010;
647                 ADV_OUTW(adv, ADV_CONFIG_LSW, cfg_lsw);
648                 adv_toggle_irq_act(adv);
649
650                 cfg_lsw = ADV_INW(adv, ADV_CONFIG_LSW) & 0xFFE0;
651                 cfg_lsw |= (irq_no & 0x07) << 2;
652                 ADV_OUTW(adv, ADV_CONFIG_LSW, cfg_lsw);
653                 adv_toggle_irq_act(adv);
654         } else if ((adv->type & ADV_ISA) != 0) {
655                 if (irq_no == 15)
656                         irq_no -= 2;
657                 irq_no -= ADV_MIN_IRQ_NO;
658                 cfg_lsw = ADV_INW(adv, ADV_CONFIG_LSW) & 0xFFF3;
659                 cfg_lsw |= (irq_no & 0x03) << 2;
660                 ADV_OUTW(adv, ADV_CONFIG_LSW, cfg_lsw);
661         }
662         return (adv_get_chip_irq(adv));
663 }
664
665 void
666 adv_set_chip_scsiid(struct adv_softc *adv, int new_id)
667 {
668         u_int16_t cfg_lsw;
669
670         cfg_lsw = ADV_INW(adv, ADV_CONFIG_LSW);
671         if (ADV_CONFIG_SCSIID(cfg_lsw) == new_id)
672                 return;
673         cfg_lsw &= ~ADV_CFG_LSW_SCSIID;
674         cfg_lsw |= (new_id & ADV_MAX_TID) << ADV_CFG_LSW_SCSIID_SHIFT;
675         ADV_OUTW(adv, ADV_CONFIG_LSW, cfg_lsw);
676 }
677
678 int
679 adv_execute_scsi_queue(struct adv_softc *adv, struct adv_scsi_q *scsiq,
680                        u_int32_t datalen)
681 {
682         struct          adv_target_transinfo* tinfo;
683         u_int32_t       *p_data_addr;
684         u_int32_t       *p_data_bcount;
685         int             disable_syn_offset_one_fix;
686         int             retval;
687         u_int           n_q_required;
688         u_int32_t       addr;
689         u_int8_t        sg_entry_cnt;
690         u_int8_t        target_ix;
691         u_int8_t        sg_entry_cnt_minus_one;
692         u_int8_t        tid_no;
693
694         scsiq->q1.q_no = 0;
695         retval = 1;  /* Default to error case */
696         target_ix = scsiq->q2.target_ix;
697         tid_no = ADV_TIX_TO_TID(target_ix);
698         tinfo = &adv->tinfo[tid_no];
699
700         if (scsiq->cdbptr[0] == REQUEST_SENSE) {
701                 /* Renegotiate if appropriate. */
702                 adv_set_syncrate(adv, /*struct cam_path */NULL,
703                                  tid_no, /*period*/0, /*offset*/0,
704                                  ADV_TRANS_CUR);
705                 if (tinfo->current.period != tinfo->goal.period) {
706                         adv_msgout_sdtr(adv, tinfo->goal.period,
707                                         tinfo->goal.offset);
708                         scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
709                 }
710         }
711
712         if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
713                 sg_entry_cnt = scsiq->sg_head->entry_cnt;
714                 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
715
716 #ifdef DIAGNOSTIC
717                 if (sg_entry_cnt <= 1) 
718                         panic("adv_execute_scsi_queue: Queue "
719                               "with QC_SG_HEAD set but %d segs.", sg_entry_cnt);
720
721                 if (sg_entry_cnt > ADV_MAX_SG_LIST)
722                         panic("adv_execute_scsi_queue: "
723                               "Queue with too many segs.");
724
725                 if ((adv->type & (ADV_ISA | ADV_VL | ADV_EISA)) != 0) {
726                         int i;
727
728                         for (i = 0; i < sg_entry_cnt_minus_one; i++) {
729                                 addr = scsiq->sg_head->sg_list[i].addr +
730                                        scsiq->sg_head->sg_list[i].bytes;
731
732                                 if ((addr & 0x0003) != 0)
733                                         panic("adv_execute_scsi_queue: SG "
734                                               "with odd address or byte count");
735                         }
736                 }
737 #endif
738                 p_data_addr =
739                     &scsiq->sg_head->sg_list[sg_entry_cnt_minus_one].addr;
740                 p_data_bcount =
741                     &scsiq->sg_head->sg_list[sg_entry_cnt_minus_one].bytes;
742
743                 n_q_required = adv_sgcount_to_qcount(sg_entry_cnt);
744                 scsiq->sg_head->queue_cnt = n_q_required - 1;
745         } else {
746                 p_data_addr = &scsiq->q1.data_addr;
747                 p_data_bcount = &scsiq->q1.data_cnt;
748                 n_q_required = 1;
749         }
750
751         disable_syn_offset_one_fix = FALSE;
752
753         if ((adv->fix_asyn_xfer & scsiq->q1.target_id) != 0
754          && (adv->fix_asyn_xfer_always & scsiq->q1.target_id) == 0) {
755
756                 if (datalen != 0) {
757                         if (datalen < 512) {
758                                 disable_syn_offset_one_fix = TRUE;
759                         } else {
760                                 if (scsiq->cdbptr[0] == INQUIRY
761                                  || scsiq->cdbptr[0] == REQUEST_SENSE
762                                  || scsiq->cdbptr[0] == READ_CAPACITY
763                                  || scsiq->cdbptr[0] == MODE_SELECT_6 
764                                  || scsiq->cdbptr[0] == MODE_SENSE_6
765                                  || scsiq->cdbptr[0] == MODE_SENSE_10 
766                                  || scsiq->cdbptr[0] == MODE_SELECT_10 
767                                  || scsiq->cdbptr[0] == READ_TOC) {
768                                         disable_syn_offset_one_fix = TRUE;
769                                 }
770                         }
771                 }
772         }
773
774         if (disable_syn_offset_one_fix) {
775                 scsiq->q2.tag_code &=
776                     ~(MSG_SIMPLE_Q_TAG|MSG_HEAD_OF_Q_TAG|MSG_ORDERED_Q_TAG);
777                 scsiq->q2.tag_code |= (ADV_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX
778                                      | ADV_TAG_FLAG_DISABLE_DISCONNECT);
779         }
780
781         if ((adv->bug_fix_control & ADV_BUG_FIX_IF_NOT_DWB) != 0
782          && (scsiq->cdbptr[0] == READ_10 || scsiq->cdbptr[0] == READ_6)) {
783                 u_int8_t extra_bytes;
784
785                 addr = *p_data_addr + *p_data_bcount;
786                 extra_bytes = addr & 0x0003;
787                 if (extra_bytes != 0
788                  && ((scsiq->q1.cntl & QC_SG_HEAD) != 0
789                   || (scsiq->q1.data_cnt & 0x01FF) == 0)) {
790                         scsiq->q2.tag_code |= ADV_TAG_FLAG_EXTRA_BYTES;
791                         scsiq->q1.extra_bytes = extra_bytes;
792                         *p_data_bcount -= extra_bytes;
793                 }
794         }
795
796         if ((adv_get_num_free_queues(adv, n_q_required) >= n_q_required)
797          || ((scsiq->q1.cntl & QC_URGENT) != 0))
798                 retval = adv_send_scsi_queue(adv, scsiq, n_q_required);
799         
800         return (retval);
801 }
802
803
804 u_int8_t
805 adv_copy_lram_doneq(struct adv_softc *adv, u_int16_t q_addr,
806                     struct adv_q_done_info *scsiq, u_int32_t max_dma_count)
807 {
808         u_int16_t val;
809         u_int8_t  sg_queue_cnt;
810
811         adv_get_q_info(adv, q_addr + ADV_SCSIQ_DONE_INFO_BEG,
812                        (u_int16_t *)scsiq,
813                        (sizeof(scsiq->d2) + sizeof(scsiq->d3)) / 2);
814
815 #if BYTE_ORDER == BIG_ENDIAN
816         adv_adj_endian_qdone_info(scsiq);
817 #endif
818
819         val = adv_read_lram_16(adv, q_addr + ADV_SCSIQ_B_STATUS);
820         scsiq->q_status = val & 0xFF;
821         scsiq->q_no = (val >> 8) & 0XFF;
822
823         val = adv_read_lram_16(adv, q_addr + ADV_SCSIQ_B_CNTL);
824         scsiq->cntl = val & 0xFF;
825         sg_queue_cnt = (val >> 8) & 0xFF;
826
827         val = adv_read_lram_16(adv,q_addr + ADV_SCSIQ_B_SENSE_LEN);
828         scsiq->sense_len = val & 0xFF;
829         scsiq->extra_bytes = (val >> 8) & 0xFF;
830
831         /*
832          * Due to a bug in accessing LRAM on the 940UA, the residual
833          * is split into separate high and low 16bit quantities.
834          */
835         scsiq->remain_bytes =
836             adv_read_lram_16(adv, q_addr + ADV_SCSIQ_DW_REMAIN_XFER_CNT);
837         scsiq->remain_bytes |=
838             adv_read_lram_16(adv, q_addr + ADV_SCSIQ_W_ALT_DC1) << 16;
839
840         /*
841          * XXX Is this just a safeguard or will the counter really
842          * have bogus upper bits?
843          */
844         scsiq->remain_bytes &= max_dma_count;
845
846         return (sg_queue_cnt);
847 }
848
849 int
850 adv_start_chip(struct adv_softc *adv)
851 {
852         ADV_OUTB(adv, ADV_CHIP_CTRL, 0);
853         if ((ADV_INW(adv, ADV_CHIP_STATUS) & ADV_CSW_HALTED) != 0)
854                 return (0);
855         return (1);
856 }
857
858 int
859 adv_stop_execution(struct adv_softc *adv)
860 {
861         int count;
862
863         count = 0;
864         if (adv_read_lram_8(adv, ADV_STOP_CODE_B) == 0) {
865                 adv_write_lram_8(adv, ADV_STOP_CODE_B,
866                                  ADV_STOP_REQ_RISC_STOP);
867                 do {
868                         if (adv_read_lram_8(adv, ADV_STOP_CODE_B) &
869                                 ADV_STOP_ACK_RISC_STOP) {
870                                 return (1);
871                         }
872                         DELAY(1000);
873                 } while (count++ < 20);
874         }
875         return (0);
876 }
877
878 int
879 adv_is_chip_halted(struct adv_softc *adv)
880 {
881         if ((ADV_INW(adv, ADV_CHIP_STATUS) & ADV_CSW_HALTED) != 0) {
882                 if ((ADV_INB(adv, ADV_CHIP_CTRL) & ADV_CC_HALT) != 0) {
883                         return (1);
884                 }
885         }
886         return (0);
887 }
888
889 /*
890  * XXX The numeric constants and the loops in this routine
891  * need to be documented.
892  */
893 void
894 adv_ack_interrupt(struct adv_softc *adv)
895 {
896         u_int8_t        host_flag;
897         u_int8_t        risc_flag;
898         int             loop;
899
900         loop = 0;
901         do {
902                 risc_flag = adv_read_lram_8(adv, ADVV_RISC_FLAG_B);
903                 if (loop++ > 0x7FFF) {
904                         break;
905                 }
906         } while ((risc_flag & ADV_RISC_FLAG_GEN_INT) != 0);
907
908         host_flag = adv_read_lram_8(adv, ADVV_HOST_FLAG_B);
909         adv_write_lram_8(adv, ADVV_HOST_FLAG_B,
910                          host_flag | ADV_HOST_FLAG_ACK_INT);
911
912         ADV_OUTW(adv, ADV_CHIP_STATUS, ADV_CIW_INT_ACK);
913         loop = 0;
914         while (ADV_INW(adv, ADV_CHIP_STATUS) & ADV_CSW_INT_PENDING) {
915                 ADV_OUTW(adv, ADV_CHIP_STATUS, ADV_CIW_INT_ACK);
916                 if (loop++ > 3) {
917                         break;
918                 }
919         }
920
921         adv_write_lram_8(adv, ADVV_HOST_FLAG_B, host_flag);
922 }
923
924 /*
925  * Handle all conditions that may halt the chip waiting
926  * for us to intervene.
927  */
928 void
929 adv_isr_chip_halted(struct adv_softc *adv)
930 {
931         u_int16_t         int_halt_code;
932         u_int16_t         halt_q_addr;
933         target_bit_vector target_mask;
934         target_bit_vector scsi_busy;
935         u_int8_t          halt_qp;
936         u_int8_t          target_ix;
937         u_int8_t          q_cntl;
938         u_int8_t          tid_no;
939
940         int_halt_code = adv_read_lram_16(adv, ADVV_HALTCODE_W);
941         halt_qp = adv_read_lram_8(adv, ADVV_CURCDB_B);
942         halt_q_addr = ADV_QNO_TO_QADDR(halt_qp);
943         target_ix = adv_read_lram_8(adv, halt_q_addr + ADV_SCSIQ_B_TARGET_IX);
944         q_cntl = adv_read_lram_8(adv, halt_q_addr + ADV_SCSIQ_B_CNTL);
945         tid_no = ADV_TIX_TO_TID(target_ix);
946         target_mask = ADV_TID_TO_TARGET_MASK(tid_no);
947         if (int_halt_code == ADV_HALT_DISABLE_ASYN_USE_SYN_FIX) {
948                 /*
949                  * Temporarily disable the async fix by removing
950                  * this target from the list of affected targets,
951                  * setting our async rate, and then putting us
952                  * back into the mask.
953                  */
954                 adv->fix_asyn_xfer &= ~target_mask;
955                 adv_set_syncrate(adv, /*struct cam_path */NULL,
956                                  tid_no, /*period*/0, /*offset*/0,
957                                  ADV_TRANS_ACTIVE);
958                 adv->fix_asyn_xfer |= target_mask;
959         } else if (int_halt_code == ADV_HALT_ENABLE_ASYN_USE_SYN_FIX) {
960                 adv_set_syncrate(adv, /*struct cam_path */NULL,
961                                  tid_no, /*period*/0, /*offset*/0,
962                                  ADV_TRANS_ACTIVE);
963         } else if (int_halt_code == ADV_HALT_EXTMSG_IN) {
964                 adv_handle_extmsg_in(adv, halt_q_addr, q_cntl,
965                                      target_mask, tid_no);
966         } else if (int_halt_code == ADV_HALT_CHK_CONDITION) {
967                 struct    adv_target_transinfo* tinfo;
968                 union     ccb *ccb;
969                 u_int32_t cinfo_index;
970                 u_int8_t  tag_code;
971                 u_int8_t  q_status;
972
973                 tinfo = &adv->tinfo[tid_no];
974                 q_cntl |= QC_REQ_SENSE;
975
976                 /* Renegotiate if appropriate. */
977                 adv_set_syncrate(adv, /*struct cam_path */NULL,
978                                  tid_no, /*period*/0, /*offset*/0,
979                                  ADV_TRANS_CUR);
980                 if (tinfo->current.period != tinfo->goal.period) {
981                         adv_msgout_sdtr(adv, tinfo->goal.period,
982                                         tinfo->goal.offset);
983                         q_cntl |= QC_MSG_OUT;
984                 }
985                 adv_write_lram_8(adv, halt_q_addr + ADV_SCSIQ_B_CNTL, q_cntl);
986
987                 /* Don't tag request sense commands */
988                 tag_code = adv_read_lram_8(adv,
989                                            halt_q_addr + ADV_SCSIQ_B_TAG_CODE);
990                 tag_code &=
991                     ~(MSG_SIMPLE_Q_TAG|MSG_HEAD_OF_Q_TAG|MSG_ORDERED_Q_TAG);
992
993                 if ((adv->fix_asyn_xfer & target_mask) != 0
994                  && (adv->fix_asyn_xfer_always & target_mask) == 0) {
995                         tag_code |= (ADV_TAG_FLAG_DISABLE_DISCONNECT
996                                  | ADV_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
997                 }
998                 adv_write_lram_8(adv, halt_q_addr + ADV_SCSIQ_B_TAG_CODE,
999                                  tag_code);
1000                 q_status = adv_read_lram_8(adv,
1001                                            halt_q_addr + ADV_SCSIQ_B_STATUS);
1002                 q_status |= (QS_READY | QS_BUSY);
1003                 adv_write_lram_8(adv, halt_q_addr + ADV_SCSIQ_B_STATUS,
1004                                  q_status);
1005                 /*
1006                  * Freeze the devq until we can handle the sense condition.
1007                  */
1008                 cinfo_index =
1009                     adv_read_lram_32(adv, halt_q_addr + ADV_SCSIQ_D_CINFO_IDX);
1010                 ccb = adv->ccb_infos[cinfo_index].ccb;
1011                 xpt_freeze_devq(ccb->ccb_h.path, /*count*/1);
1012                 ccb->ccb_h.status |= CAM_DEV_QFRZN;
1013                 adv_abort_ccb(adv, tid_no, ADV_TIX_TO_LUN(target_ix),
1014                               /*ccb*/NULL, CAM_REQUEUE_REQ,
1015                               /*queued_only*/TRUE);
1016                 scsi_busy = adv_read_lram_8(adv, ADVV_SCSIBUSY_B);
1017                 scsi_busy &= ~target_mask;
1018                 adv_write_lram_8(adv, ADVV_SCSIBUSY_B, scsi_busy);
1019                 /*
1020                  * Ensure we have enough time to actually
1021                  * retrieve the sense.
1022                  */
1023                 callout_reset(&ccb->ccb_h.timeout_ch, 5 * hz, adv_timeout, ccb);
1024         } else if (int_halt_code == ADV_HALT_SDTR_REJECTED) {
1025                 struct  ext_msg out_msg;
1026
1027                 adv_read_lram_16_multi(adv, ADVV_MSGOUT_BEG,
1028                                        (u_int16_t *) &out_msg,
1029                                        sizeof(out_msg)/2);
1030
1031                 if ((out_msg.msg_type == MSG_EXTENDED)
1032                  && (out_msg.msg_len == MSG_EXT_SDTR_LEN)
1033                  && (out_msg.msg_req == MSG_EXT_SDTR)) {
1034
1035                         /* Revert to Async */
1036                         adv_set_syncrate(adv, /*struct cam_path */NULL,
1037                                          tid_no, /*period*/0, /*offset*/0,
1038                                          ADV_TRANS_GOAL|ADV_TRANS_ACTIVE);
1039                 }
1040                 q_cntl &= ~QC_MSG_OUT;
1041                 adv_write_lram_8(adv, halt_q_addr + ADV_SCSIQ_B_CNTL, q_cntl);
1042         } else if (int_halt_code == ADV_HALT_SS_QUEUE_FULL) {
1043                 u_int8_t scsi_status;
1044                 union ccb *ccb;
1045                 u_int32_t cinfo_index;
1046                 
1047                 scsi_status = adv_read_lram_8(adv, halt_q_addr
1048                                               + ADV_SCSIQ_SCSI_STATUS);
1049                 cinfo_index =
1050                     adv_read_lram_32(adv, halt_q_addr + ADV_SCSIQ_D_CINFO_IDX);
1051                 ccb = adv->ccb_infos[cinfo_index].ccb;
1052                 xpt_freeze_devq(ccb->ccb_h.path, /*count*/1);
1053                 ccb->ccb_h.status |= CAM_DEV_QFRZN|CAM_SCSI_STATUS_ERROR;
1054                 ccb->csio.scsi_status = SCSI_STATUS_QUEUE_FULL; 
1055                 adv_abort_ccb(adv, tid_no, ADV_TIX_TO_LUN(target_ix),
1056                               /*ccb*/NULL, CAM_REQUEUE_REQ,
1057                               /*queued_only*/TRUE);
1058                 scsi_busy = adv_read_lram_8(adv, ADVV_SCSIBUSY_B);
1059                 scsi_busy &= ~target_mask;
1060                 adv_write_lram_8(adv, ADVV_SCSIBUSY_B, scsi_busy);              
1061         } else {
1062                 printf("Unhandled Halt Code %x\n", int_halt_code);
1063         }
1064         adv_write_lram_16(adv, ADVV_HALTCODE_W, 0);
1065 }
1066
1067 void
1068 adv_sdtr_to_period_offset(struct adv_softc *adv,
1069                           u_int8_t sync_data, u_int8_t *period,
1070                           u_int8_t *offset, int tid)
1071 {
1072         if (adv->fix_asyn_xfer & ADV_TID_TO_TARGET_MASK(tid)
1073          && (sync_data == ASYN_SDTR_DATA_FIX_PCI_REV_AB)) {
1074                 *period = *offset = 0;
1075         } else {
1076                 *period = adv->sdtr_period_tbl[((sync_data >> 4) & 0xF)];
1077                 *offset = sync_data & 0xF;
1078         }
1079 }
1080
1081 void
1082 adv_set_syncrate(struct adv_softc *adv, struct cam_path *path,
1083                  u_int tid, u_int period, u_int offset, u_int type)
1084 {
1085         struct adv_target_transinfo* tinfo;
1086         u_int old_period;
1087         u_int old_offset;
1088         u_int8_t sdtr_data;
1089
1090         tinfo = &adv->tinfo[tid];
1091
1092         /* Filter our input */
1093         sdtr_data = adv_period_offset_to_sdtr(adv, &period,
1094                                               &offset, tid);
1095
1096         old_period = tinfo->current.period;
1097         old_offset = tinfo->current.offset;
1098
1099         if ((type & ADV_TRANS_CUR) != 0
1100          && ((old_period != period || old_offset != offset)
1101           || period == 0 || offset == 0) /*Changes in asyn fix settings*/) {
1102                 int halted;
1103
1104                 crit_enter();
1105                 halted = adv_is_chip_halted(adv);
1106                 if (halted == 0)
1107                         /* Must halt the chip first */
1108                         adv_host_req_chip_halt(adv);
1109
1110                 /* Update current hardware settings */
1111                 adv_set_sdtr_reg_at_id(adv, tid, sdtr_data);
1112
1113                 /*
1114                  * If a target can run in sync mode, we don't need
1115                  * to check it for sync problems.
1116                  */
1117                 if (offset != 0)
1118                         adv->fix_asyn_xfer &= ~ADV_TID_TO_TARGET_MASK(tid);
1119
1120                 if (halted == 0)
1121                         /* Start the chip again */
1122                         adv_start_chip(adv);
1123
1124                 crit_exit();
1125                 tinfo->current.period = period;
1126                 tinfo->current.offset = offset;
1127
1128                 if (path != NULL) {
1129                         /*
1130                          * Tell the SCSI layer about the
1131                          * new transfer parameters.
1132                          */
1133                         struct  ccb_trans_settings neg;
1134
1135                         neg.sync_period = period;
1136                         neg.sync_offset = offset;
1137                         neg.valid = CCB_TRANS_SYNC_RATE_VALID
1138                                   | CCB_TRANS_SYNC_OFFSET_VALID;
1139                         xpt_setup_ccb(&neg.ccb_h, path, /*priority*/1);
1140                         xpt_async(AC_TRANSFER_NEG, path, &neg);
1141                 }
1142         }
1143
1144         if ((type & ADV_TRANS_GOAL) != 0) {
1145                 tinfo->goal.period = period;
1146                 tinfo->goal.offset = offset;
1147         }
1148
1149         if ((type & ADV_TRANS_USER) != 0) {
1150                 tinfo->user.period = period;
1151                 tinfo->user.offset = offset;
1152         }
1153 }
1154
1155 u_int8_t
1156 adv_period_offset_to_sdtr(struct adv_softc *adv, u_int *period,
1157                           u_int *offset, int tid)
1158 {
1159         u_int i;
1160         u_int dummy_offset;
1161         u_int dummy_period;
1162
1163         if (offset == NULL) {
1164                 dummy_offset = 0;
1165                 offset = &dummy_offset;
1166         }
1167
1168         if (period == NULL) {
1169                 dummy_period = 0;
1170                 period = &dummy_period;
1171         }
1172
1173         *offset = MIN(ADV_SYN_MAX_OFFSET, *offset);
1174         if (*period != 0 && *offset != 0) {
1175                 for (i = 0; i < adv->sdtr_period_tbl_size; i++) {
1176                         if (*period <= adv->sdtr_period_tbl[i]) {
1177                                 /*       
1178                                  * When responding to a target that requests
1179                                  * sync, the requested  rate may fall between
1180                                  * two rates that we can output, but still be
1181                                  * a rate that we can receive.  Because of this,
1182                                  * we want to respond to the target with
1183                                  * the same rate that it sent to us even
1184                                  * if the period we use to send data to it
1185                                  * is lower.  Only lower the response period
1186                                  * if we must.
1187                                  */        
1188                                 if (i == 0 /* Our maximum rate */)
1189                                         *period = adv->sdtr_period_tbl[0];
1190                                 return ((i << 4) | *offset);
1191                         }
1192                 }
1193         }
1194         
1195         /* Must go async */
1196         *period = 0;
1197         *offset = 0;
1198         if (adv->fix_asyn_xfer & ADV_TID_TO_TARGET_MASK(tid))
1199                 return (ASYN_SDTR_DATA_FIX_PCI_REV_AB);
1200         return (0);
1201 }
1202
1203 /* Internal Routines */
1204
1205 static void
1206 adv_read_lram_16_multi(struct adv_softc *adv, u_int16_t s_addr,
1207                        u_int16_t *buffer, int count)
1208 {
1209         ADV_OUTW(adv, ADV_LRAM_ADDR, s_addr);
1210         ADV_INSW(adv, ADV_LRAM_DATA, buffer, count);
1211 }
1212
1213 static void
1214 adv_write_lram_16_multi(struct adv_softc *adv, u_int16_t s_addr,
1215                         u_int16_t *buffer, int count)
1216 {
1217         ADV_OUTW(adv, ADV_LRAM_ADDR, s_addr);
1218         ADV_OUTSW(adv, ADV_LRAM_DATA, buffer, count);
1219 }
1220
1221 static void
1222 adv_mset_lram_16(struct adv_softc *adv, u_int16_t s_addr,
1223                  u_int16_t set_value, int count)
1224 {
1225         ADV_OUTW(adv, ADV_LRAM_ADDR, s_addr);
1226         bus_space_set_multi_2(adv->tag, adv->bsh, ADV_LRAM_DATA,
1227                               set_value, count);
1228 }
1229
1230 static u_int32_t
1231 adv_msum_lram_16(struct adv_softc *adv, u_int16_t s_addr, int count)
1232 {
1233         u_int32_t       sum;
1234         int             i;
1235
1236         sum = 0;
1237         ADV_OUTW(adv, ADV_LRAM_ADDR, s_addr);
1238         for (i = 0; i < count; i++)
1239                 sum += ADV_INW(adv, ADV_LRAM_DATA);
1240         return (sum);
1241 }
1242
1243 static int
1244 adv_write_and_verify_lram_16(struct adv_softc *adv, u_int16_t addr,
1245                              u_int16_t value)
1246 {
1247         int     retval;
1248
1249         retval = 0;
1250         ADV_OUTW(adv, ADV_LRAM_ADDR, addr);
1251         ADV_OUTW(adv, ADV_LRAM_DATA, value);
1252         DELAY(10000);
1253         ADV_OUTW(adv, ADV_LRAM_ADDR, addr);
1254         if (value != ADV_INW(adv, ADV_LRAM_DATA))
1255                 retval = 1;
1256         return (retval);
1257 }
1258
1259 static u_int32_t
1260 adv_read_lram_32(struct adv_softc *adv, u_int16_t addr)
1261 {
1262         u_int16_t           val_low, val_high;
1263
1264         ADV_OUTW(adv, ADV_LRAM_ADDR, addr);
1265
1266 #if BYTE_ORDER == BIG_ENDIAN
1267         val_high = ADV_INW(adv, ADV_LRAM_DATA);
1268         val_low = ADV_INW(adv, ADV_LRAM_DATA);
1269 #else
1270         val_low = ADV_INW(adv, ADV_LRAM_DATA);
1271         val_high = ADV_INW(adv, ADV_LRAM_DATA);
1272 #endif
1273
1274         return (((u_int32_t)val_high << 16) | (u_int32_t)val_low);
1275 }
1276
1277 static void
1278 adv_write_lram_32(struct adv_softc *adv, u_int16_t addr, u_int32_t value)
1279 {
1280         ADV_OUTW(adv, ADV_LRAM_ADDR, addr);
1281
1282 #if BYTE_ORDER == BIG_ENDIAN
1283         ADV_OUTW(adv, ADV_LRAM_DATA, (u_int16_t)((value >> 16) & 0xFFFF));
1284         ADV_OUTW(adv, ADV_LRAM_DATA, (u_int16_t)(value & 0xFFFF));
1285 #else
1286         ADV_OUTW(adv, ADV_LRAM_DATA, (u_int16_t)(value & 0xFFFF));
1287         ADV_OUTW(adv, ADV_LRAM_DATA, (u_int16_t)((value >> 16) & 0xFFFF));
1288 #endif
1289 }
1290
1291 static void
1292 adv_write_lram_32_multi(struct adv_softc *adv, u_int16_t s_addr,
1293                         u_int32_t *buffer, int count)
1294 {
1295         ADV_OUTW(adv, ADV_LRAM_ADDR, s_addr);
1296         ADV_OUTSW(adv, ADV_LRAM_DATA, (u_int16_t *)buffer, count * 2);
1297 }
1298
1299 static u_int16_t
1300 adv_read_eeprom_16(struct adv_softc *adv, u_int8_t addr)
1301 {
1302         u_int16_t read_wval;
1303         u_int8_t  cmd_reg;
1304
1305         adv_write_eeprom_cmd_reg(adv, ADV_EEPROM_CMD_WRITE_DISABLE);
1306         DELAY(1000);
1307         cmd_reg = addr | ADV_EEPROM_CMD_READ;
1308         adv_write_eeprom_cmd_reg(adv, cmd_reg);
1309         DELAY(1000);
1310         read_wval = ADV_INW(adv, ADV_EEPROM_DATA);
1311         DELAY(1000);
1312         return (read_wval);
1313 }
1314
1315 static u_int16_t
1316 adv_write_eeprom_16(struct adv_softc *adv, u_int8_t addr, u_int16_t value)
1317 {
1318         u_int16_t       read_value;
1319
1320         read_value = adv_read_eeprom_16(adv, addr);
1321         if (read_value != value) {
1322                 adv_write_eeprom_cmd_reg(adv, ADV_EEPROM_CMD_WRITE_ENABLE);
1323                 DELAY(1000);
1324                 
1325                 ADV_OUTW(adv, ADV_EEPROM_DATA, value);
1326                 DELAY(1000);
1327
1328                 adv_write_eeprom_cmd_reg(adv, ADV_EEPROM_CMD_WRITE | addr);
1329                 DELAY(20 * 1000);
1330
1331                 adv_write_eeprom_cmd_reg(adv, ADV_EEPROM_CMD_WRITE_DISABLE);
1332                 DELAY(1000);
1333                 read_value = adv_read_eeprom_16(adv, addr);
1334         }
1335         return (read_value);
1336 }
1337
1338 static int
1339 adv_write_eeprom_cmd_reg(struct adv_softc *adv, u_int8_t cmd_reg)
1340 {
1341         u_int8_t read_back;
1342         int      retry;
1343
1344         retry = 0;
1345         while (1) {
1346                 ADV_OUTB(adv, ADV_EEPROM_CMD, cmd_reg);
1347                 DELAY(1000);
1348                 read_back = ADV_INB(adv, ADV_EEPROM_CMD);
1349                 if (read_back == cmd_reg) {
1350                         return (1);
1351                 }
1352                 if (retry++ > ADV_EEPROM_MAX_RETRY) {
1353                         return (0);
1354                 }
1355         }
1356 }
1357
1358 static int
1359 adv_set_eeprom_config_once(struct adv_softc *adv,
1360                            struct adv_eeprom_config *eeprom_config)
1361 {
1362         int             n_error;
1363         u_int16_t       *wbuf;
1364         u_int16_t       sum;
1365         u_int8_t        s_addr;
1366         u_int8_t        cfg_beg;
1367         u_int8_t        cfg_end;
1368
1369         wbuf = (u_int16_t *)eeprom_config;
1370         n_error = 0;
1371         sum = 0;
1372         for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
1373                 sum += *wbuf;
1374                 if (*wbuf != adv_write_eeprom_16(adv, s_addr, *wbuf)) {
1375                         n_error++;
1376                 }
1377         }
1378         if (adv->type & ADV_VL) {
1379                 cfg_beg = ADV_EEPROM_CFG_BEG_VL;
1380                 cfg_end = ADV_EEPROM_MAX_ADDR_VL;
1381         } else {
1382                 cfg_beg = ADV_EEPROM_CFG_BEG;
1383                 cfg_end = ADV_EEPROM_MAX_ADDR;
1384         }
1385
1386         for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
1387                 sum += *wbuf;
1388                 if (*wbuf != adv_write_eeprom_16(adv, s_addr, *wbuf)) {
1389                         n_error++;
1390                 }
1391         }
1392         *wbuf = sum;
1393         if (sum != adv_write_eeprom_16(adv, s_addr, sum)) {
1394                 n_error++;
1395         }
1396         wbuf = (u_int16_t *)eeprom_config;
1397         for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
1398                 if (*wbuf != adv_read_eeprom_16(adv, s_addr)) {
1399                         n_error++;
1400                 }
1401         }
1402         for (s_addr = cfg_beg; s_addr <= cfg_end; s_addr++, wbuf++) {
1403                 if (*wbuf != adv_read_eeprom_16(adv, s_addr)) {
1404                         n_error++;
1405                 }
1406         }
1407         return (n_error);
1408 }
1409
1410 static u_int32_t
1411 adv_load_microcode(struct adv_softc *adv, u_int16_t s_addr,
1412                    u_int16_t *mcode_buf, u_int16_t mcode_size)
1413 {
1414         u_int32_t chksum;
1415         u_int16_t mcode_lram_size;
1416         u_int16_t mcode_chksum;
1417
1418         mcode_lram_size = mcode_size >> 1;
1419         /* XXX Why zero the memory just before you write the whole thing?? */
1420         adv_mset_lram_16(adv, s_addr, 0, mcode_lram_size);
1421         adv_write_lram_16_multi(adv, s_addr, mcode_buf, mcode_lram_size);
1422
1423         chksum = adv_msum_lram_16(adv, s_addr, mcode_lram_size);
1424         mcode_chksum = (u_int16_t)adv_msum_lram_16(adv, ADV_CODE_SEC_BEG,
1425                                                    ((mcode_size - s_addr
1426                                                      - ADV_CODE_SEC_BEG) >> 1));
1427         adv_write_lram_16(adv, ADVV_MCODE_CHKSUM_W, mcode_chksum);
1428         adv_write_lram_16(adv, ADVV_MCODE_SIZE_W, mcode_size);
1429         return (chksum);
1430 }
1431
1432 static void
1433 adv_reinit_lram(struct adv_softc *adv) {
1434         adv_init_lram(adv);
1435         adv_init_qlink_var(adv);
1436 }
1437
1438 static void
1439 adv_init_lram(struct adv_softc *adv)
1440 {
1441         u_int8_t  i;
1442         u_int16_t s_addr;
1443
1444         adv_mset_lram_16(adv, ADV_QADR_BEG, 0,
1445                          (((adv->max_openings + 2 + 1) * 64) >> 1));
1446         
1447         i = ADV_MIN_ACTIVE_QNO;
1448         s_addr = ADV_QADR_BEG + ADV_QBLK_SIZE;
1449
1450         adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_FWD, i + 1);
1451         adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_BWD, adv->max_openings);
1452         adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_QNO, i);
1453         i++;
1454         s_addr += ADV_QBLK_SIZE;
1455         for (; i < adv->max_openings; i++, s_addr += ADV_QBLK_SIZE) {
1456                 adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_FWD, i + 1);
1457                 adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_BWD, i - 1);
1458                 adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_QNO, i);
1459         }
1460
1461         adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_FWD, ADV_QLINK_END);
1462         adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_BWD, adv->max_openings - 1);
1463         adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_QNO, adv->max_openings);
1464         i++;
1465         s_addr += ADV_QBLK_SIZE;
1466
1467         for (; i <= adv->max_openings + 3; i++, s_addr += ADV_QBLK_SIZE) {
1468                 adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_FWD, i);
1469                 adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_BWD, i);
1470                 adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_QNO, i);
1471         }
1472 }
1473
1474 static int
1475 adv_init_microcode_var(struct adv_softc *adv)
1476 {
1477         int      i;
1478
1479         for (i = 0; i <= ADV_MAX_TID; i++) {
1480                 
1481                 /* Start out async all around */
1482                 adv_set_syncrate(adv, /*path*/NULL,
1483                                  i, 0, 0,
1484                                  ADV_TRANS_GOAL|ADV_TRANS_CUR);
1485         }
1486
1487         adv_init_qlink_var(adv);
1488
1489         adv_write_lram_8(adv, ADVV_DISC_ENABLE_B, adv->disc_enable);
1490         adv_write_lram_8(adv, ADVV_HOSTSCSI_ID_B, 0x01 << adv->scsi_id);
1491
1492         adv_write_lram_32(adv, ADVV_OVERRUN_PADDR_D, adv->overrun_physbase);
1493
1494         adv_write_lram_32(adv, ADVV_OVERRUN_BSIZE_D, ADV_OVERRUN_BSIZE);
1495
1496         ADV_OUTW(adv, ADV_REG_PROG_COUNTER, ADV_MCODE_START_ADDR);
1497         if (ADV_INW(adv, ADV_REG_PROG_COUNTER) != ADV_MCODE_START_ADDR) {
1498                 printf("adv%d: Unable to set program counter. Aborting.\n",
1499                        adv->unit);
1500                 return (1);
1501         }
1502         return (0);
1503 }
1504
1505 static void
1506 adv_init_qlink_var(struct adv_softc *adv)
1507 {
1508         int       i;
1509         u_int16_t lram_addr;
1510
1511         adv_write_lram_8(adv, ADVV_NEXTRDY_B, 1);
1512         adv_write_lram_8(adv, ADVV_DONENEXT_B, adv->max_openings);
1513
1514         adv_write_lram_16(adv, ADVV_FREE_Q_HEAD_W, 1);
1515         adv_write_lram_16(adv, ADVV_DONE_Q_TAIL_W, adv->max_openings);
1516
1517         adv_write_lram_8(adv, ADVV_BUSY_QHEAD_B,
1518                          (u_int8_t)((int) adv->max_openings + 1));
1519         adv_write_lram_8(adv, ADVV_DISC1_QHEAD_B,
1520                          (u_int8_t)((int) adv->max_openings + 2));
1521
1522         adv_write_lram_8(adv, ADVV_TOTAL_READY_Q_B, adv->max_openings);
1523
1524         adv_write_lram_16(adv, ADVV_ASCDVC_ERR_CODE_W, 0);
1525         adv_write_lram_16(adv, ADVV_HALTCODE_W, 0);
1526         adv_write_lram_8(adv, ADVV_STOP_CODE_B, 0);
1527         adv_write_lram_8(adv, ADVV_SCSIBUSY_B, 0);
1528         adv_write_lram_8(adv, ADVV_WTM_FLAG_B, 0);
1529         adv_write_lram_8(adv, ADVV_Q_DONE_IN_PROGRESS_B, 0);
1530
1531         lram_addr = ADV_QADR_BEG;
1532         for (i = 0; i < 32; i++, lram_addr += 2)
1533                 adv_write_lram_16(adv, lram_addr, 0);
1534 }
1535
1536 static void
1537 adv_disable_interrupt(struct adv_softc *adv)
1538 {
1539         u_int16_t cfg;
1540
1541         cfg = ADV_INW(adv, ADV_CONFIG_LSW);
1542         ADV_OUTW(adv, ADV_CONFIG_LSW, cfg & ~ADV_CFG_LSW_HOST_INT_ON);
1543 }
1544
1545 static void
1546 adv_enable_interrupt(struct adv_softc *adv)
1547 {
1548         u_int16_t cfg;
1549
1550         cfg = ADV_INW(adv, ADV_CONFIG_LSW);
1551         ADV_OUTW(adv, ADV_CONFIG_LSW, cfg | ADV_CFG_LSW_HOST_INT_ON);
1552 }
1553
1554 static void
1555 adv_toggle_irq_act(struct adv_softc *adv)
1556 {
1557         ADV_OUTW(adv, ADV_CHIP_STATUS, ADV_CIW_IRQ_ACT);
1558         ADV_OUTW(adv, ADV_CHIP_STATUS, 0);
1559 }
1560
1561 void
1562 adv_start_execution(struct adv_softc *adv)
1563 {
1564         if (adv_read_lram_8(adv, ADV_STOP_CODE_B) != 0) {
1565                 adv_write_lram_8(adv, ADV_STOP_CODE_B, 0);
1566         }
1567 }
1568
1569 int
1570 adv_stop_chip(struct adv_softc *adv)
1571 {
1572         u_int8_t cc_val;
1573
1574         cc_val = ADV_INB(adv, ADV_CHIP_CTRL)
1575                  & (~(ADV_CC_SINGLE_STEP | ADV_CC_TEST | ADV_CC_DIAG));
1576         ADV_OUTB(adv, ADV_CHIP_CTRL, cc_val | ADV_CC_HALT);
1577         adv_set_chip_ih(adv, ADV_INS_HALT);
1578         adv_set_chip_ih(adv, ADV_INS_RFLAG_WTM);
1579         if ((ADV_INW(adv, ADV_CHIP_STATUS) & ADV_CSW_HALTED) == 0) {
1580                 return (0);
1581         }
1582         return (1);
1583 }
1584
1585 static int
1586 adv_host_req_chip_halt(struct adv_softc *adv)
1587 {       
1588         int      count;
1589         u_int8_t saved_stop_code;
1590
1591         if (adv_is_chip_halted(adv))
1592                 return (1);
1593
1594         count = 0;
1595         saved_stop_code = adv_read_lram_8(adv, ADVV_STOP_CODE_B);
1596         adv_write_lram_8(adv, ADVV_STOP_CODE_B,
1597                          ADV_STOP_HOST_REQ_RISC_HALT | ADV_STOP_REQ_RISC_STOP);
1598         while (adv_is_chip_halted(adv) == 0
1599             && count++ < 2000)
1600                 ;
1601
1602         adv_write_lram_8(adv, ADVV_STOP_CODE_B, saved_stop_code);
1603         return (count < 2000); 
1604 }
1605
1606 static void
1607 adv_set_chip_ih(struct adv_softc *adv, u_int16_t ins_code)
1608 {
1609         adv_set_bank(adv, 1);
1610         ADV_OUTW(adv, ADV_REG_IH, ins_code);
1611         adv_set_bank(adv, 0);
1612 }
1613
1614 #if UNUSED
1615 static u_int8_t
1616 adv_get_chip_scsi_ctrl(struct adv_softc *adv)
1617 {
1618         u_int8_t scsi_ctrl;
1619
1620         adv_set_bank(adv, 1);
1621         scsi_ctrl = ADV_INB(adv, ADV_REG_SC);
1622         adv_set_bank(adv, 0);
1623         return (scsi_ctrl);
1624 }
1625 #endif
1626
1627 /*
1628  * XXX Looks like more padding issues in this routine as well.
1629  *     There has to be a way to turn this into an insw.
1630  */
1631 static void
1632 adv_get_q_info(struct adv_softc *adv, u_int16_t s_addr,
1633                u_int16_t *inbuf, int words)
1634 {
1635         int     i;
1636
1637         ADV_OUTW(adv, ADV_LRAM_ADDR, s_addr);
1638         for (i = 0; i < words; i++, inbuf++) {
1639                 if (i == 5) {
1640                         continue;
1641                 }
1642                 *inbuf = ADV_INW(adv, ADV_LRAM_DATA);
1643         }
1644 }
1645
1646 static u_int
1647 adv_get_num_free_queues(struct adv_softc *adv, u_int8_t n_qs)
1648 {
1649         u_int     cur_used_qs;
1650         u_int     cur_free_qs;
1651
1652         cur_used_qs = adv->cur_active + ADV_MIN_FREE_Q;
1653
1654         if ((cur_used_qs + n_qs) <= adv->max_openings) {
1655                 cur_free_qs = adv->max_openings - cur_used_qs;
1656                 return (cur_free_qs);
1657         }
1658         adv->openings_needed = n_qs;
1659         return (0);
1660 }
1661
1662 static u_int8_t
1663 adv_alloc_free_queues(struct adv_softc *adv, u_int8_t free_q_head,
1664                       u_int8_t n_free_q)
1665 {
1666         int i;
1667
1668         for (i = 0; i < n_free_q; i++) {
1669                 free_q_head = adv_alloc_free_queue(adv, free_q_head);
1670                 if (free_q_head == ADV_QLINK_END)
1671                         break;
1672         }
1673         return (free_q_head);
1674 }
1675
1676 static u_int8_t
1677 adv_alloc_free_queue(struct adv_softc *adv, u_int8_t free_q_head)
1678 {
1679         u_int16_t       q_addr;
1680         u_int8_t        next_qp;
1681         u_int8_t        q_status;
1682
1683         next_qp = ADV_QLINK_END;
1684         q_addr = ADV_QNO_TO_QADDR(free_q_head);
1685         q_status = adv_read_lram_8(adv, q_addr + ADV_SCSIQ_B_STATUS);
1686         
1687         if ((q_status & QS_READY) == 0)
1688                 next_qp = adv_read_lram_8(adv, q_addr + ADV_SCSIQ_B_FWD);
1689
1690         return (next_qp);
1691 }
1692
1693 static int
1694 adv_send_scsi_queue(struct adv_softc *adv, struct adv_scsi_q *scsiq,
1695                     u_int8_t n_q_required)
1696 {
1697         u_int8_t        free_q_head;
1698         u_int8_t        next_qp;
1699         u_int8_t        tid_no;
1700         u_int8_t        target_ix;
1701         int             retval;
1702
1703         retval = 1;
1704         target_ix = scsiq->q2.target_ix;
1705         tid_no = ADV_TIX_TO_TID(target_ix);
1706         free_q_head = adv_read_lram_16(adv, ADVV_FREE_Q_HEAD_W) & 0xFF;
1707         if ((next_qp = adv_alloc_free_queues(adv, free_q_head, n_q_required))
1708             != ADV_QLINK_END) {
1709                 scsiq->q1.q_no = free_q_head;
1710
1711                 /*
1712                  * Now that we know our Q number, point our sense
1713                  * buffer pointer to a bus dma mapped area where
1714                  * we can dma the data to.
1715                  */
1716                 scsiq->q1.sense_addr = adv->sense_physbase
1717                     + ((free_q_head - 1) * sizeof(struct scsi_sense_data));
1718                 adv_put_ready_sg_list_queue(adv, scsiq, free_q_head);
1719                 adv_write_lram_16(adv, ADVV_FREE_Q_HEAD_W, next_qp);
1720                 adv->cur_active += n_q_required;
1721                 retval = 0;
1722         }
1723         return (retval);
1724 }
1725
1726
1727 static void
1728 adv_put_ready_sg_list_queue(struct adv_softc *adv, struct adv_scsi_q *scsiq,
1729                             u_int q_no)
1730 {
1731         u_int8_t        sg_list_dwords;
1732         u_int8_t        sg_index, i;
1733         u_int8_t        sg_entry_cnt;
1734         u_int8_t        next_qp;
1735         u_int16_t       q_addr;
1736         struct          adv_sg_head *sg_head;
1737         struct          adv_sg_list_q scsi_sg_q;
1738
1739         sg_head = scsiq->sg_head;
1740
1741         if (sg_head) {
1742                 sg_entry_cnt = sg_head->entry_cnt - 1;
1743 #ifdef DIAGNOSTIC
1744                 if (sg_entry_cnt == 0)
1745                         panic("adv_put_ready_sg_list_queue: ScsiQ with "
1746                               "a SG list but only one element");
1747                 if ((scsiq->q1.cntl & QC_SG_HEAD) == 0)
1748                         panic("adv_put_ready_sg_list_queue: ScsiQ with "
1749                               "a SG list but QC_SG_HEAD not set");
1750 #endif                  
1751                 q_addr = ADV_QNO_TO_QADDR(q_no);
1752                 sg_index = 1;
1753                 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
1754                 scsi_sg_q.sg_head_qp = q_no;
1755                 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
1756                 for (i = 0; i < sg_head->queue_cnt; i++) {
1757                         u_int8_t segs_this_q;
1758
1759                         if (sg_entry_cnt > ADV_SG_LIST_PER_Q)
1760                                 segs_this_q = ADV_SG_LIST_PER_Q;
1761                         else {
1762                                 /* This will be the last segment then */
1763                                 segs_this_q = sg_entry_cnt;
1764                                 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
1765                         }
1766                         scsi_sg_q.seq_no = i + 1;
1767                         sg_list_dwords = segs_this_q << 1;
1768                         if (i == 0) {
1769                                 scsi_sg_q.sg_list_cnt = segs_this_q;
1770                                 scsi_sg_q.sg_cur_list_cnt = segs_this_q;
1771                         } else {
1772                                 scsi_sg_q.sg_list_cnt = segs_this_q - 1;
1773                                 scsi_sg_q.sg_cur_list_cnt = segs_this_q - 1;
1774                         }
1775                         next_qp = adv_read_lram_8(adv, q_addr + ADV_SCSIQ_B_FWD);
1776                         scsi_sg_q.q_no = next_qp;
1777                         q_addr = ADV_QNO_TO_QADDR(next_qp);
1778
1779                         adv_write_lram_16_multi(adv,
1780                                                 q_addr + ADV_SCSIQ_SGHD_CPY_BEG,
1781                                                 (u_int16_t *)&scsi_sg_q,
1782                                                 sizeof(scsi_sg_q) >> 1);
1783                         adv_write_lram_32_multi(adv, q_addr + ADV_SGQ_LIST_BEG,
1784                                                 (u_int32_t *)&sg_head->sg_list[sg_index],
1785                                                 sg_list_dwords);
1786                         sg_entry_cnt -= segs_this_q;
1787                         sg_index += ADV_SG_LIST_PER_Q;
1788                 }
1789         }
1790         adv_put_ready_queue(adv, scsiq, q_no);
1791 }
1792
1793 static void
1794 adv_put_ready_queue(struct adv_softc *adv, struct adv_scsi_q *scsiq,
1795                     u_int q_no)
1796 {
1797         struct          adv_target_transinfo* tinfo;
1798         u_int           q_addr;
1799         u_int           tid_no;
1800
1801         tid_no = ADV_TIX_TO_TID(scsiq->q2.target_ix);
1802         tinfo = &adv->tinfo[tid_no];
1803         if ((tinfo->current.period != tinfo->goal.period)
1804          || (tinfo->current.offset != tinfo->goal.offset)) {
1805
1806                 adv_msgout_sdtr(adv, tinfo->goal.period, tinfo->goal.offset);
1807                 scsiq->q1.cntl |= QC_MSG_OUT;
1808         }
1809         q_addr = ADV_QNO_TO_QADDR(q_no);
1810
1811         scsiq->q1.status = QS_FREE;
1812
1813         adv_write_lram_16_multi(adv, q_addr + ADV_SCSIQ_CDB_BEG,
1814                                 (u_int16_t *)scsiq->cdbptr,
1815                                 scsiq->q2.cdb_len >> 1);
1816
1817 #if BYTE_ORDER == BIG_ENDIAN
1818         adv_adj_scsiq_endian(scsiq);
1819 #endif
1820
1821         adv_put_scsiq(adv, q_addr + ADV_SCSIQ_CPY_BEG,
1822                       (u_int16_t *) &scsiq->q1.cntl,
1823                       ((sizeof(scsiq->q1) + sizeof(scsiq->q2)) / 2) - 1);
1824
1825 #if CC_WRITE_IO_COUNT
1826         adv_write_lram_16(adv, q_addr + ADV_SCSIQ_W_REQ_COUNT,
1827                           adv->req_count);
1828 #endif
1829
1830 #if CC_CLEAR_DMA_REMAIN
1831
1832         adv_write_lram_32(adv, q_addr + ADV_SCSIQ_DW_REMAIN_XFER_ADDR, 0);
1833         adv_write_lram_32(adv, q_addr + ADV_SCSIQ_DW_REMAIN_XFER_CNT, 0);
1834 #endif
1835
1836         adv_write_lram_16(adv, q_addr + ADV_SCSIQ_B_STATUS,
1837                           (scsiq->q1.q_no << 8) | QS_READY);
1838 }
1839
1840 static void
1841 adv_put_scsiq(struct adv_softc *adv, u_int16_t s_addr,
1842               u_int16_t *buffer, int words)
1843 {
1844         int     i;
1845
1846         /*
1847          * XXX This routine makes *gross* assumptions
1848          * about padding in the data structures.
1849          * Either the data structures should have explicit
1850          * padding members added, or they should have padding
1851          * turned off via compiler attributes depending on
1852          * which yields better overall performance.  My hunch
1853          * would be that turning off padding would be the
1854          * faster approach as an outsw is much faster than
1855          * this crude loop and accessing un-aligned data
1856          * members isn't *that* expensive.  The other choice
1857          * would be to modify the ASC script so that the
1858          * the adv_scsiq_1 structure can be re-arranged so
1859          * padding isn't required.
1860          */
1861         ADV_OUTW(adv, ADV_LRAM_ADDR, s_addr);
1862         for (i = 0; i < words; i++, buffer++) {
1863                 if (i == 2 || i == 10) {
1864                         continue;
1865                 }
1866                 ADV_OUTW(adv, ADV_LRAM_DATA, *buffer);
1867         }
1868 }
1869
1870 static void
1871 adv_handle_extmsg_in(struct adv_softc *adv, u_int16_t halt_q_addr,
1872                      u_int8_t q_cntl, target_bit_vector target_mask,
1873                      int tid_no)
1874 {
1875         struct  ext_msg ext_msg;
1876
1877         adv_read_lram_16_multi(adv, ADVV_MSGIN_BEG, (u_int16_t *) &ext_msg,
1878                                sizeof(ext_msg) >> 1);
1879         if ((ext_msg.msg_type == MSG_EXTENDED)
1880          && (ext_msg.msg_req == MSG_EXT_SDTR)
1881          && (ext_msg.msg_len == MSG_EXT_SDTR_LEN)) {
1882                 union     ccb *ccb;
1883                 struct    adv_target_transinfo* tinfo;
1884                 u_int32_t cinfo_index;
1885                 u_int    period;
1886                 u_int    offset;
1887                 int      sdtr_accept;
1888                 u_int8_t orig_offset;
1889
1890                 cinfo_index =
1891                     adv_read_lram_32(adv, halt_q_addr + ADV_SCSIQ_D_CINFO_IDX);
1892                 ccb = adv->ccb_infos[cinfo_index].ccb;
1893                 tinfo = &adv->tinfo[tid_no];
1894                 sdtr_accept = TRUE;
1895
1896                 orig_offset = ext_msg.req_ack_offset;
1897                 if (ext_msg.xfer_period < tinfo->goal.period) {
1898                         sdtr_accept = FALSE;
1899                         ext_msg.xfer_period = tinfo->goal.period;
1900                 }
1901
1902                 /* Perform range checking */
1903                 period = ext_msg.xfer_period;
1904                 offset = ext_msg.req_ack_offset;
1905                 adv_period_offset_to_sdtr(adv, &period,  &offset, tid_no);
1906                 ext_msg.xfer_period = period;
1907                 ext_msg.req_ack_offset = offset;
1908                 
1909                 /* Record our current sync settings */
1910                 adv_set_syncrate(adv, ccb->ccb_h.path,
1911                                  tid_no, ext_msg.xfer_period,
1912                                  ext_msg.req_ack_offset,
1913                                  ADV_TRANS_GOAL|ADV_TRANS_ACTIVE);
1914
1915                 /* Offset too high or large period forced async */
1916                 if (orig_offset != ext_msg.req_ack_offset)
1917                         sdtr_accept = FALSE;
1918
1919                 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
1920                         /* Valid response to our requested negotiation */
1921                         q_cntl &= ~QC_MSG_OUT;
1922                 } else {
1923                         /* Must Respond */
1924                         q_cntl |= QC_MSG_OUT;
1925                         adv_msgout_sdtr(adv, ext_msg.xfer_period,
1926                                         ext_msg.req_ack_offset);
1927                 }
1928
1929         } else if (ext_msg.msg_type == MSG_EXTENDED
1930                 && ext_msg.msg_req == MSG_EXT_WDTR
1931                 && ext_msg.msg_len == MSG_EXT_WDTR_LEN) {
1932
1933                 ext_msg.wdtr_width = 0;
1934                 adv_write_lram_16_multi(adv, ADVV_MSGOUT_BEG,
1935                                         (u_int16_t *)&ext_msg,
1936                                         sizeof(ext_msg) >> 1);
1937                 q_cntl |= QC_MSG_OUT;
1938         } else {
1939
1940                 ext_msg.msg_type = MSG_MESSAGE_REJECT;
1941                 adv_write_lram_16_multi(adv, ADVV_MSGOUT_BEG,
1942                                         (u_int16_t *)&ext_msg,
1943                                         sizeof(ext_msg) >> 1);
1944                 q_cntl |= QC_MSG_OUT;
1945         }
1946         adv_write_lram_8(adv, halt_q_addr + ADV_SCSIQ_B_CNTL, q_cntl);
1947 }
1948
1949 static void
1950 adv_msgout_sdtr(struct adv_softc *adv, u_int8_t sdtr_period,
1951                 u_int8_t sdtr_offset)
1952 {
1953         struct   ext_msg sdtr_buf;
1954
1955         sdtr_buf.msg_type = MSG_EXTENDED;
1956         sdtr_buf.msg_len = MSG_EXT_SDTR_LEN;
1957         sdtr_buf.msg_req = MSG_EXT_SDTR;
1958         sdtr_buf.xfer_period = sdtr_period;
1959         sdtr_offset &= ADV_SYN_MAX_OFFSET;
1960         sdtr_buf.req_ack_offset = sdtr_offset;
1961         adv_write_lram_16_multi(adv, ADVV_MSGOUT_BEG,
1962                                 (u_int16_t *) &sdtr_buf,
1963                                 sizeof(sdtr_buf) / 2);
1964 }
1965
1966 int
1967 adv_abort_ccb(struct adv_softc *adv, int target, int lun, union ccb *ccb,
1968               u_int32_t status, int queued_only)
1969 {
1970         u_int16_t q_addr;
1971         u_int8_t  q_no;
1972         struct adv_q_done_info scsiq_buf;
1973         struct adv_q_done_info *scsiq;
1974         u_int8_t  target_ix;
1975         int       count;
1976
1977         scsiq = &scsiq_buf;
1978         target_ix = ADV_TIDLUN_TO_IX(target, lun);
1979         count = 0;
1980         for (q_no = ADV_MIN_ACTIVE_QNO; q_no <= adv->max_openings; q_no++) {
1981                 struct adv_ccb_info *ccb_info;
1982                 q_addr = ADV_QNO_TO_QADDR(q_no);
1983
1984                 adv_copy_lram_doneq(adv, q_addr, scsiq, adv->max_dma_count);
1985                 ccb_info = &adv->ccb_infos[scsiq->d2.ccb_index];
1986                 if (((scsiq->q_status & QS_READY) != 0)
1987                  && ((scsiq->q_status & QS_ABORTED) == 0)
1988                  && ((scsiq->cntl & QCSG_SG_XFER_LIST) == 0)
1989                  && (scsiq->d2.target_ix == target_ix)
1990                  && (queued_only == 0
1991                   || !(scsiq->q_status & (QS_DISC1|QS_DISC2|QS_BUSY|QS_DONE)))
1992                  && (ccb == NULL || (ccb == ccb_info->ccb))) {
1993                         union ccb *aborted_ccb;
1994                         struct adv_ccb_info *cinfo;
1995
1996                         scsiq->q_status |= QS_ABORTED;
1997                         adv_write_lram_8(adv, q_addr + ADV_SCSIQ_B_STATUS,
1998                                          scsiq->q_status);
1999                         aborted_ccb = ccb_info->ccb;
2000                         /* Don't clobber earlier error codes */
2001                         if ((aborted_ccb->ccb_h.status & CAM_STATUS_MASK)
2002                           == CAM_REQ_INPROG)
2003                                 aborted_ccb->ccb_h.status |= status;
2004                         cinfo = (struct adv_ccb_info *)
2005                             aborted_ccb->ccb_h.ccb_cinfo_ptr;
2006                         cinfo->state |= ACCB_ABORT_QUEUED;
2007                         count++;
2008                 }
2009         }
2010         return (count);
2011 }
2012
2013 int
2014 adv_reset_bus(struct adv_softc *adv, int initiate_bus_reset)
2015 {
2016         int count; 
2017         int i;
2018         union ccb *ccb;
2019
2020         i = 200;
2021         while ((ADV_INW(adv, ADV_CHIP_STATUS) & ADV_CSW_SCSI_RESET_ACTIVE) != 0
2022             && i--)
2023                 DELAY(1000);
2024         adv_reset_chip(adv, initiate_bus_reset);
2025         adv_reinit_lram(adv);
2026         for (i = 0; i <= ADV_MAX_TID; i++)
2027                 adv_set_syncrate(adv, NULL, i, /*period*/0,
2028                                  /*offset*/0, ADV_TRANS_CUR);
2029         ADV_OUTW(adv, ADV_REG_PROG_COUNTER, ADV_MCODE_START_ADDR);
2030
2031         /* Tell the XPT layer that a bus reset occured */
2032         if (adv->path != NULL)
2033                 xpt_async(AC_BUS_RESET, adv->path, NULL);
2034
2035         count = 0;
2036         while ((ccb = (union ccb *)LIST_FIRST(&adv->pending_ccbs)) != NULL) {
2037                 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG)
2038                         ccb->ccb_h.status |= CAM_SCSI_BUS_RESET;
2039                 adv_done(adv, ccb, QD_ABORTED_BY_HOST, 0, 0, 0);
2040                 count++;
2041         }
2042
2043         adv_start_chip(adv);
2044         return (count);
2045 }
2046
2047 static void
2048 adv_set_sdtr_reg_at_id(struct adv_softc *adv, int tid, u_int8_t sdtr_data)
2049 {
2050         int orig_id;
2051
2052         adv_set_bank(adv, 1);
2053         orig_id = ffs(ADV_INB(adv, ADV_HOST_SCSIID)) - 1;
2054         ADV_OUTB(adv, ADV_HOST_SCSIID, tid);
2055         if (ADV_INB(adv, ADV_HOST_SCSIID) == (0x01 << tid)) {
2056                 adv_set_bank(adv, 0);
2057                 ADV_OUTB(adv, ADV_SYN_OFFSET, sdtr_data);
2058         }
2059         adv_set_bank(adv, 1);
2060         ADV_OUTB(adv, ADV_HOST_SCSIID, orig_id);
2061         adv_set_bank(adv, 0);
2062 }