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