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