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