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