1 | /* $NetBSD: adwlib.c,v 1.41 2013/09/12 11:23:37 martin Exp $ */ |
2 | |
3 | /* |
4 | * Low level routines for the Advanced Systems Inc. SCSI controllers chips |
5 | * |
6 | * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc. |
7 | * All rights reserved. |
8 | * |
9 | * Author: Baldassare Dante Profeta <dante@mclink.it> |
10 | * |
11 | * Redistribution and use in source and binary forms, with or without |
12 | * modification, are permitted provided that the following conditions |
13 | * are met: |
14 | * 1. Redistributions of source code must retain the above copyright |
15 | * notice, this list of conditions and the following disclaimer. |
16 | * 2. Redistributions in binary form must reproduce the above copyright |
17 | * notice, this list of conditions and the following disclaimer in the |
18 | * documentation and/or other materials provided with the distribution. |
19 | * 3. All advertising materials mentioning features or use of this software |
20 | * must display the following acknowledgement: |
21 | * This product includes software developed by the NetBSD |
22 | * Foundation, Inc. and its contributors. |
23 | * 4. Neither the name of The NetBSD Foundation nor the names of its |
24 | * contributors may be used to endorse or promote products derived |
25 | * from this software without specific prior written permission. |
26 | * |
27 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
28 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
29 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
30 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
31 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
32 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
33 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
34 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
35 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
36 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
37 | * POSSIBILITY OF SUCH DAMAGE. |
38 | */ |
39 | /* |
40 | * Ported from: |
41 | */ |
42 | /* |
43 | * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters |
44 | * |
45 | * Copyright (c) 1995-2000 Advanced System Products, Inc. |
46 | * All Rights Reserved. |
47 | * |
48 | * Redistribution and use in source and binary forms, with or without |
49 | * modification, are permitted provided that redistributions of source |
50 | * code retain the above copyright notice and this comment without |
51 | * modification. |
52 | */ |
53 | |
54 | #include <sys/cdefs.h> |
55 | __KERNEL_RCSID(0, "$NetBSD: adwlib.c,v 1.41 2013/09/12 11:23:37 martin Exp $" ); |
56 | |
57 | #include <sys/param.h> |
58 | #include <sys/systm.h> |
59 | #include <sys/malloc.h> |
60 | #include <sys/kernel.h> |
61 | #include <sys/queue.h> |
62 | #include <sys/device.h> |
63 | |
64 | #include <sys/bus.h> |
65 | #include <sys/intr.h> |
66 | |
67 | #include <dev/scsipi/scsi_all.h> |
68 | #include <dev/scsipi/scsipi_all.h> |
69 | #include <dev/scsipi/scsiconf.h> |
70 | |
71 | #include <dev/pci/pcidevs.h> |
72 | |
73 | #include <dev/ic/adwlib.h> |
74 | #include <dev/ic/adwmcode.h> |
75 | #include <dev/ic/adw.h> |
76 | |
77 | |
78 | /* Static Functions */ |
79 | |
80 | int AdwRamSelfTest(bus_space_tag_t, bus_space_handle_t, u_int8_t); |
81 | int AdwLoadMCode(bus_space_tag_t, bus_space_handle_t, u_int16_t *, u_int8_t); |
82 | int AdwASC3550Cabling(bus_space_tag_t, bus_space_handle_t, ADW_DVC_CFG *); |
83 | int AdwASC38C0800Cabling(bus_space_tag_t, bus_space_handle_t, ADW_DVC_CFG *); |
84 | int AdwASC38C1600Cabling(bus_space_tag_t, bus_space_handle_t, ADW_DVC_CFG *); |
85 | |
86 | static u_int16_t AdwGetEEPROMConfig(bus_space_tag_t, bus_space_handle_t, |
87 | ADW_EEPROM *); |
88 | static void AdwSetEEPROMConfig(bus_space_tag_t, bus_space_handle_t, |
89 | ADW_EEPROM *); |
90 | static u_int16_t AdwReadEEPWord(bus_space_tag_t, bus_space_handle_t, int); |
91 | static void AdwWaitEEPCmd(bus_space_tag_t, bus_space_handle_t); |
92 | |
93 | static void AdwInquiryHandling(ADW_SOFTC *, ADW_SCSI_REQ_Q *); |
94 | |
95 | static void AdwSleepMilliSecond(u_int32_t); |
96 | static void AdwDelayMicroSecond(u_int32_t); |
97 | |
98 | |
99 | /* |
100 | * EEPROM Configuration. |
101 | * |
102 | * All drivers should use this structure to set the default EEPROM |
103 | * configuration. The BIOS now uses this structure when it is built. |
104 | * Additional structure information can be found in adwlib.h where |
105 | * the structure is defined. |
106 | */ |
107 | static const ADW_EEPROM adw_3550_Default_EEPROM = { |
108 | ADW_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */ |
109 | 0x0000, /* 01 cfg_msw */ |
110 | 0xFFFF, /* 02 disc_enable */ |
111 | 0xFFFF, /* 03 wdtr_able */ |
112 | { 0xFFFF }, /* 04 sdtr_able */ |
113 | 0xFFFF, /* 05 start_motor */ |
114 | 0xFFFF, /* 06 tagqng_able */ |
115 | 0xFFFF, /* 07 bios_scan */ |
116 | 0, /* 08 scam_tolerant */ |
117 | 7, /* 09 adapter_scsi_id */ |
118 | 0, /* bios_boot_delay */ |
119 | 3, /* 10 scsi_reset_delay */ |
120 | 0, /* bios_id_lun */ |
121 | 0, /* 11 termination */ |
122 | 0, /* reserved1 */ |
123 | 0xFFE7, /* 12 bios_ctrl */ |
124 | { 0xFFFF }, /* 13 ultra_able */ |
125 | { 0 }, /* 14 reserved2 */ |
126 | ADW_DEF_MAX_HOST_QNG, /* 15 max_host_qng */ |
127 | ADW_DEF_MAX_DVC_QNG, /* max_dvc_qng */ |
128 | 0, /* 16 dvc_cntl */ |
129 | { 0 }, /* 17 bug_fix */ |
130 | { 0,0,0 }, /* 18-20 serial_number[3] */ |
131 | 0, /* 21 check_sum */ |
132 | { /* 22-29 oem_name[16] */ |
133 | 0,0,0,0,0,0,0,0, |
134 | 0,0,0,0,0,0,0,0 |
135 | }, |
136 | 0, /* 30 dvc_err_code */ |
137 | 0, /* 31 adv_err_code */ |
138 | 0, /* 32 adv_err_addr */ |
139 | 0, /* 33 saved_dvc_err_code */ |
140 | 0, /* 34 saved_adv_err_code */ |
141 | 0, /* 35 saved_adv_err_addr */ |
142 | { /* 36-55 reserved1[16] */ |
143 | 0,0,0,0,0,0,0,0,0,0, |
144 | 0,0,0,0,0,0,0,0,0,0 |
145 | }, |
146 | 0, /* 56 cisptr_lsw */ |
147 | 0, /* 57 cisprt_msw */ |
148 | 0, /* 58 subsysvid */ |
149 | 0, /* 59 subsysid */ |
150 | { 0,0,0,0 } /* 60-63 reserved2[4] */ |
151 | }; |
152 | |
153 | static const ADW_EEPROM adw_38C0800_Default_EEPROM = { |
154 | ADW_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */ |
155 | 0x0000, /* 01 cfg_msw */ |
156 | 0xFFFF, /* 02 disc_enable */ |
157 | 0xFFFF, /* 03 wdtr_able */ |
158 | { 0x4444 }, /* 04 sdtr_speed1 */ |
159 | 0xFFFF, /* 05 start_motor */ |
160 | 0xFFFF, /* 06 tagqng_able */ |
161 | 0xFFFF, /* 07 bios_scan */ |
162 | 0, /* 08 scam_tolerant */ |
163 | 7, /* 09 adapter_scsi_id */ |
164 | 0, /* bios_boot_delay */ |
165 | 3, /* 10 scsi_reset_delay */ |
166 | 0, /* bios_id_lun */ |
167 | 0, /* 11 termination_se */ |
168 | 0, /* termination_lvd */ |
169 | 0xFFE7, /* 12 bios_ctrl */ |
170 | { 0x4444 }, /* 13 sdtr_speed2 */ |
171 | { 0x4444 }, /* 14 sdtr_speed3 */ |
172 | ADW_DEF_MAX_HOST_QNG, /* 15 max_host_qng */ |
173 | ADW_DEF_MAX_DVC_QNG, /* max_dvc_qng */ |
174 | 0, /* 16 dvc_cntl */ |
175 | { 0x4444 }, /* 17 sdtr_speed4 */ |
176 | { 0,0,0 }, /* 18-20 serial_number[3] */ |
177 | 0, /* 21 check_sum */ |
178 | { /* 22-29 oem_name[16] */ |
179 | 0,0,0,0,0,0,0,0, |
180 | 0,0,0,0,0,0,0,0 |
181 | }, |
182 | 0, /* 30 dvc_err_code */ |
183 | 0, /* 31 adv_err_code */ |
184 | 0, /* 32 adv_err_addr */ |
185 | 0, /* 33 saved_dvc_err_code */ |
186 | 0, /* 34 saved_adv_err_code */ |
187 | 0, /* 35 saved_adv_err_addr */ |
188 | { /* 36-55 reserved1[16] */ |
189 | 0,0,0,0,0,0,0,0,0,0, |
190 | 0,0,0,0,0,0,0,0,0,0 |
191 | }, |
192 | 0, /* 56 cisptr_lsw */ |
193 | 0, /* 57 cisprt_msw */ |
194 | PCI_VENDOR_ADVSYS, /* 58 subsysvid */ |
195 | PCI_PRODUCT_ADVSYS_U2W, /* 59 subsysid */ |
196 | { 0,0,0,0 } /* 60-63 reserved2[4] */ |
197 | }; |
198 | |
199 | static const ADW_EEPROM adw_38C1600_Default_EEPROM = { |
200 | ADW_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */ |
201 | 0x0000, /* 01 cfg_msw */ |
202 | 0xFFFF, /* 02 disc_enable */ |
203 | 0xFFFF, /* 03 wdtr_able */ |
204 | { 0x5555 }, /* 04 sdtr_speed1 */ |
205 | 0xFFFF, /* 05 start_motor */ |
206 | 0xFFFF, /* 06 tagqng_able */ |
207 | 0xFFFF, /* 07 bios_scan */ |
208 | 0, /* 08 scam_tolerant */ |
209 | 7, /* 09 adapter_scsi_id */ |
210 | 0, /* bios_boot_delay */ |
211 | 3, /* 10 scsi_reset_delay */ |
212 | 0, /* bios_id_lun */ |
213 | 0, /* 11 termination_se */ |
214 | 0, /* termination_lvd */ |
215 | 0xFFE7, /* 12 bios_ctrl */ |
216 | { 0x5555 }, /* 13 sdtr_speed2 */ |
217 | { 0x5555 }, /* 14 sdtr_speed3 */ |
218 | ADW_DEF_MAX_HOST_QNG, /* 15 max_host_qng */ |
219 | ADW_DEF_MAX_DVC_QNG, /* max_dvc_qng */ |
220 | 0, /* 16 dvc_cntl */ |
221 | { 0x5555 }, /* 17 sdtr_speed4 */ |
222 | { 0,0,0 }, /* 18-20 serial_number[3] */ |
223 | 0, /* 21 check_sum */ |
224 | { /* 22-29 oem_name[16] */ |
225 | 0,0,0,0,0,0,0,0, |
226 | 0,0,0,0,0,0,0,0 |
227 | }, |
228 | 0, /* 30 dvc_err_code */ |
229 | 0, /* 31 adv_err_code */ |
230 | 0, /* 32 adv_err_addr */ |
231 | 0, /* 33 saved_dvc_err_code */ |
232 | 0, /* 34 saved_adv_err_code */ |
233 | 0, /* 35 saved_adv_err_addr */ |
234 | { /* 36-55 reserved1[16] */ |
235 | 0,0,0,0,0,0,0,0,0,0, |
236 | 0,0,0,0,0,0,0,0,0,0 |
237 | }, |
238 | 0, /* 56 cisptr_lsw */ |
239 | 0, /* 57 cisprt_msw */ |
240 | PCI_VENDOR_ADVSYS, /* 58 subsysvid */ |
241 | PCI_PRODUCT_ADVSYS_U3W, /* 59 subsysid */ |
242 | { 0,0,0,0 } /* 60-63 reserved2[4] */ |
243 | }; |
244 | |
245 | |
246 | /* |
247 | * Read the board's EEPROM configuration. Set fields in ADW_SOFTC and |
248 | * ADW_DVC_CFG based on the EEPROM settings. The chip is stopped while |
249 | * all of this is done. |
250 | * |
251 | * For a non-fatal error return a warning code. If there are no warnings |
252 | * then 0 is returned. |
253 | * |
254 | * Note: Chip is stopped on entry. |
255 | */ |
256 | int |
257 | AdwInitFromEEPROM(ADW_SOFTC *sc) |
258 | { |
259 | bus_space_tag_t iot = sc->sc_iot; |
260 | bus_space_handle_t ioh = sc->sc_ioh; |
261 | ADW_EEPROM eep_config; |
262 | u_int16_t warn_code; |
263 | u_int16_t sdtr_speed = 0; |
264 | u_int8_t tid, termination; |
265 | int i, j; |
266 | |
267 | |
268 | warn_code = 0; |
269 | |
270 | /* |
271 | * Read the board's EEPROM configuration. |
272 | * |
273 | * Set default values if a bad checksum is found. |
274 | * |
275 | * XXX - Don't handle big-endian access to EEPROM yet. |
276 | */ |
277 | if (AdwGetEEPROMConfig(iot, ioh, &eep_config) != eep_config.check_sum) { |
278 | warn_code |= ADW_WARN_EEPROM_CHKSUM; |
279 | |
280 | /* |
281 | * Set EEPROM default values. |
282 | */ |
283 | switch(sc->chip_type) { |
284 | case ADW_CHIP_ASC3550: |
285 | eep_config = adw_3550_Default_EEPROM; |
286 | break; |
287 | case ADW_CHIP_ASC38C0800: |
288 | eep_config = adw_38C0800_Default_EEPROM; |
289 | break; |
290 | case ADW_CHIP_ASC38C1600: |
291 | eep_config = adw_38C1600_Default_EEPROM; |
292 | |
293 | #if 0 |
294 | XXX TODO!!! if (ASC_PCI_ID2FUNC(sc->cfg.pci_slot_info) != 0) { |
295 | #endif |
296 | if (sc->cfg.pci_slot_info != 0) { |
297 | u_int8_t lsw_msb; |
298 | |
299 | lsw_msb = eep_config.cfg_lsw >> 8; |
300 | /* |
301 | * Set Function 1 EEPROM Word 0 MSB |
302 | * |
303 | * Clear the BIOS_ENABLE (bit 14) and |
304 | * INTAB (bit 11) EEPROM bits. |
305 | * |
306 | * Disable Bit 14 (BIOS_ENABLE) to fix |
307 | * SPARC Ultra 60 and old Mac system booting |
308 | * problem. The Expansion ROM must |
309 | * be disabled in Function 1 for these systems. |
310 | */ |
311 | lsw_msb &= ~(((ADW_EEPROM_BIOS_ENABLE | |
312 | ADW_EEPROM_INTAB) >> 8) & 0xFF); |
313 | /* |
314 | * Set the INTAB (bit 11) if the GPIO 0 input |
315 | * indicates the Function 1 interrupt line is |
316 | * wired to INTA. |
317 | * |
318 | * Set/Clear Bit 11 (INTAB) from |
319 | * the GPIO bit 0 input: |
320 | * 1 - Function 1 intr line wired to INT A. |
321 | * 0 - Function 1 intr line wired to INT B. |
322 | * |
323 | * Note: Adapter boards always have Function 0 |
324 | * wired to INTA. |
325 | * Put all 5 GPIO bits in input mode and then |
326 | * read their input values. |
327 | */ |
328 | ADW_WRITE_BYTE_REGISTER(iot, ioh, |
329 | IOPB_GPIO_CNTL, 0); |
330 | if (ADW_READ_BYTE_REGISTER(iot, ioh, |
331 | IOPB_GPIO_DATA) & 0x01) { |
332 | /* |
333 | * Function 1 interrupt wired to INTA; |
334 | * Set EEPROM bit. |
335 | */ |
336 | lsw_msb |= (ADW_EEPROM_INTAB >> 8) |
337 | & 0xFF; |
338 | } |
339 | eep_config.cfg_lsw &= 0x00FF; |
340 | eep_config.cfg_lsw |= lsw_msb << 8; |
341 | } |
342 | break; |
343 | } |
344 | |
345 | /* |
346 | * Assume the 6 byte board serial number that was read |
347 | * from EEPROM is correct even if the EEPROM checksum |
348 | * failed. |
349 | */ |
350 | for (i=2, j=1; i>=0; i--, j++) { |
351 | eep_config.serial_number[i] = |
352 | AdwReadEEPWord(iot, ioh, ASC_EEP_DVC_CFG_END - j); |
353 | } |
354 | |
355 | AdwSetEEPROMConfig(iot, ioh, &eep_config); |
356 | } |
357 | /* |
358 | * Set sc and sc->cfg variables from the EEPROM configuration |
359 | * that was read. |
360 | * |
361 | * This is the mapping of EEPROM fields to Adw Library fields. |
362 | */ |
363 | sc->wdtr_able = eep_config.wdtr_able; |
364 | if (sc->chip_type == ADW_CHIP_ASC3550) { |
365 | sc->sdtr_able = eep_config.sdtr1.sdtr_able; |
366 | sc->ultra_able = eep_config.sdtr2.ultra_able; |
367 | } else { |
368 | sc->sdtr_speed1 = eep_config.sdtr1.sdtr_speed1; |
369 | sc->sdtr_speed2 = eep_config.sdtr2.sdtr_speed2; |
370 | sc->sdtr_speed3 = eep_config.sdtr3.sdtr_speed3; |
371 | sc->sdtr_speed4 = eep_config.sdtr4.sdtr_speed4; |
372 | } |
373 | sc->ppr_able = 0; |
374 | sc->tagqng_able = eep_config.tagqng_able; |
375 | sc->cfg.disc_enable = eep_config.disc_enable; |
376 | sc->max_host_qng = eep_config.max_host_qng; |
377 | sc->max_dvc_qng = eep_config.max_dvc_qng; |
378 | sc->chip_scsi_id = (eep_config.adapter_scsi_id & ADW_MAX_TID); |
379 | sc->start_motor = eep_config.start_motor; |
380 | sc->scsi_reset_wait = eep_config.scsi_reset_delay; |
381 | sc->bios_ctrl = eep_config.bios_ctrl; |
382 | sc->no_scam = eep_config.scam_tolerant; |
383 | sc->cfg.serial1 = eep_config.serial_number[0]; |
384 | sc->cfg.serial2 = eep_config.serial_number[1]; |
385 | sc->cfg.serial3 = eep_config.serial_number[2]; |
386 | |
387 | if (sc->chip_type == ADW_CHIP_ASC38C0800 || |
388 | sc->chip_type == ADW_CHIP_ASC38C1600) { |
389 | sc->sdtr_able = 0; |
390 | for (tid = 0; tid <= ADW_MAX_TID; tid++) { |
391 | if (tid == 0) { |
392 | sdtr_speed = sc->sdtr_speed1; |
393 | } else if (tid == 4) { |
394 | sdtr_speed = sc->sdtr_speed2; |
395 | } else if (tid == 8) { |
396 | sdtr_speed = sc->sdtr_speed3; |
397 | } else if (tid == 12) { |
398 | sdtr_speed = sc->sdtr_speed4; |
399 | } |
400 | if (sdtr_speed & ADW_MAX_TID) { |
401 | sc->sdtr_able |= (1 << tid); |
402 | } |
403 | sdtr_speed >>= 4; |
404 | } |
405 | } |
406 | |
407 | /* |
408 | * Set the host maximum queuing (max. 253, min. 16) and the per device |
409 | * maximum queuing (max. 63, min. 4). |
410 | */ |
411 | if (eep_config.max_host_qng > ADW_DEF_MAX_HOST_QNG) { |
412 | eep_config.max_host_qng = ADW_DEF_MAX_HOST_QNG; |
413 | } else if (eep_config.max_host_qng < ADW_DEF_MIN_HOST_QNG) |
414 | { |
415 | /* If the value is zero, assume it is uninitialized. */ |
416 | if (eep_config.max_host_qng == 0) { |
417 | eep_config.max_host_qng = ADW_DEF_MAX_HOST_QNG; |
418 | } else { |
419 | eep_config.max_host_qng = ADW_DEF_MIN_HOST_QNG; |
420 | } |
421 | } |
422 | |
423 | if (eep_config.max_dvc_qng > ADW_DEF_MAX_DVC_QNG) { |
424 | eep_config.max_dvc_qng = ADW_DEF_MAX_DVC_QNG; |
425 | } else if (eep_config.max_dvc_qng < ADW_DEF_MIN_DVC_QNG) { |
426 | /* If the value is zero, assume it is uninitialized. */ |
427 | if (eep_config.max_dvc_qng == 0) { |
428 | eep_config.max_dvc_qng = ADW_DEF_MAX_DVC_QNG; |
429 | } else { |
430 | eep_config.max_dvc_qng = ADW_DEF_MIN_DVC_QNG; |
431 | } |
432 | } |
433 | |
434 | /* |
435 | * If 'max_dvc_qng' is greater than 'max_host_qng', then |
436 | * set 'max_dvc_qng' to 'max_host_qng'. |
437 | */ |
438 | if (eep_config.max_dvc_qng > eep_config.max_host_qng) { |
439 | eep_config.max_dvc_qng = eep_config.max_host_qng; |
440 | } |
441 | |
442 | /* |
443 | * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng' |
444 | * values based on possibly adjusted EEPROM values. |
445 | */ |
446 | sc->max_host_qng = eep_config.max_host_qng; |
447 | sc->max_dvc_qng = eep_config.max_dvc_qng; |
448 | |
449 | |
450 | /* |
451 | * If the EEPROM 'termination' field is set to automatic (0), then set |
452 | * the ADV_DVC_CFG 'termination' field to automatic also. |
453 | * |
454 | * If the termination is specified with a non-zero 'termination' |
455 | * value check that a legal value is set and set the ADV_DVC_CFG |
456 | * 'termination' field appropriately. |
457 | */ |
458 | |
459 | switch(sc->chip_type) { |
460 | case ADW_CHIP_ASC3550: |
461 | sc->cfg.termination = 0; /* auto termination */ |
462 | switch(eep_config.termination_se) { |
463 | case 3: |
464 | /* Enable manual control with low on / high on. */ |
465 | sc->cfg.termination |= ADW_TERM_CTL_L; |
466 | case 2: |
467 | /* Enable manual control with low off / high on. */ |
468 | sc->cfg.termination |= ADW_TERM_CTL_H; |
469 | case 1: |
470 | /* Enable manual control with low off / high off. */ |
471 | sc->cfg.termination |= ADW_TERM_CTL_SEL; |
472 | case 0: |
473 | break; |
474 | default: |
475 | warn_code |= ADW_WARN_EEPROM_TERMINATION; |
476 | } |
477 | break; |
478 | |
479 | case ADW_CHIP_ASC38C0800: |
480 | case ADW_CHIP_ASC38C1600: |
481 | switch(eep_config.termination_se) { |
482 | case 0: |
483 | /* auto termination for SE */ |
484 | termination = 0; |
485 | break; |
486 | case 1: |
487 | /* Enable manual control with low off / high off. */ |
488 | termination = 0; |
489 | break; |
490 | case 2: |
491 | /* Enable manual control with low off / high on. */ |
492 | termination = ADW_TERM_SE_HI; |
493 | break; |
494 | case 3: |
495 | /* Enable manual control with low on / high on. */ |
496 | termination = ADW_TERM_SE; |
497 | break; |
498 | default: |
499 | /* |
500 | * The EEPROM 'termination_se' field contains a |
501 | * bad value. Use automatic termination instead. |
502 | */ |
503 | termination = 0; |
504 | warn_code |= ADW_WARN_EEPROM_TERMINATION; |
505 | } |
506 | |
507 | switch(eep_config.termination_lvd) { |
508 | case 0: |
509 | /* auto termination for LVD */ |
510 | sc->cfg.termination = termination; |
511 | break; |
512 | case 1: |
513 | /* Enable manual control with low off / high off. */ |
514 | sc->cfg.termination = termination; |
515 | break; |
516 | case 2: |
517 | /* Enable manual control with low off / high on. */ |
518 | sc->cfg.termination = termination | ADW_TERM_LVD_HI; |
519 | break; |
520 | case 3: |
521 | /* Enable manual control with low on / high on. */ |
522 | sc->cfg.termination = termination | ADW_TERM_LVD; |
523 | break; |
524 | default: |
525 | /* |
526 | * The EEPROM 'termination_lvd' field contains a |
527 | * bad value. Use automatic termination instead. |
528 | */ |
529 | sc->cfg.termination = termination; |
530 | warn_code |= ADW_WARN_EEPROM_TERMINATION; |
531 | } |
532 | break; |
533 | } |
534 | |
535 | return warn_code; |
536 | } |
537 | |
538 | |
539 | /* |
540 | * Initialize the ASC-3550/ASC-38C0800/ASC-38C1600. |
541 | * |
542 | * On failure return the error code. |
543 | */ |
544 | int |
545 | AdwInitDriver(ADW_SOFTC *sc) |
546 | { |
547 | bus_space_tag_t iot = sc->sc_iot; |
548 | bus_space_handle_t ioh = sc->sc_ioh; |
549 | u_int16_t error_code; |
550 | int word; |
551 | int i; |
552 | u_int16_t bios_mem[ADW_MC_BIOSLEN/2]; /* BIOS RISC Memory |
553 | 0x40-0x8F. */ |
554 | u_int16_t wdtr_able = 0, sdtr_able, /* ppr_able, */ tagqng_able; |
555 | u_int8_t max_cmd[ADW_MAX_TID + 1]; |
556 | u_int8_t tid; |
557 | |
558 | |
559 | error_code = 0; |
560 | |
561 | /* |
562 | * Save the RISC memory BIOS region before writing the microcode. |
563 | * The BIOS may already be loaded and using its RISC LRAM region |
564 | * so its region must be saved and restored. |
565 | * |
566 | * Note: This code makes the assumption, which is currently true, |
567 | * that a chip reset does not clear RISC LRAM. |
568 | */ |
569 | for (i = 0; i < ADW_MC_BIOSLEN/2; i++) { |
570 | ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_BIOSMEM+(2*i), bios_mem[i]); |
571 | } |
572 | |
573 | /* |
574 | * Save current per TID negotiated values. |
575 | */ |
576 | switch (sc->chip_type) { |
577 | case ADW_CHIP_ASC3550: |
578 | if (bios_mem[(ADW_MC_BIOS_SIGNATURE-ADW_MC_BIOSMEM)/2]==0x55AA){ |
579 | |
580 | u_int16_t bios_version, major, minor; |
581 | |
582 | bios_version = bios_mem[(ADW_MC_BIOS_VERSION - |
583 | ADW_MC_BIOSMEM) / 2]; |
584 | major = (bios_version >> 12) & 0xF; |
585 | minor = (bios_version >> 8) & 0xF; |
586 | if (major < 3 || (major == 3 && minor == 1)) { |
587 | /* |
588 | * BIOS 3.1 and earlier location of |
589 | * 'wdtr_able' variable. |
590 | */ |
591 | ADW_READ_WORD_LRAM(iot, ioh, 0x120, wdtr_able); |
592 | } else { |
593 | ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_WDTR_ABLE, |
594 | wdtr_able); |
595 | } |
596 | } |
597 | break; |
598 | |
599 | case ADW_CHIP_ASC38C1600: |
600 | /* ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_PPR_ABLE, ppr_able); */ |
601 | /* FALLTHROUGH */ |
602 | case ADW_CHIP_ASC38C0800: |
603 | ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_WDTR_ABLE, wdtr_able); |
604 | break; |
605 | } |
606 | ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_SDTR_ABLE, sdtr_able); |
607 | ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_TAGQNG_ABLE, tagqng_able); |
608 | for (tid = 0; tid <= ADW_MAX_TID; tid++) { |
609 | ADW_READ_BYTE_LRAM(iot, ioh, ADW_MC_NUMBER_OF_MAX_CMD + tid, |
610 | max_cmd[tid]); |
611 | } |
612 | |
613 | /* |
614 | * Perform a RAM Built-In Self Test |
615 | */ |
616 | if((error_code = AdwRamSelfTest(iot, ioh, sc->chip_type))) { |
617 | return error_code; |
618 | } |
619 | |
620 | /* |
621 | * Load the Microcode |
622 | */ |
623 | ; |
624 | if((error_code = AdwLoadMCode(iot, ioh, bios_mem, sc->chip_type))) { |
625 | return error_code; |
626 | } |
627 | |
628 | /* |
629 | * Read microcode version and date. |
630 | */ |
631 | ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_VERSION_DATE, sc->cfg.mcode_date); |
632 | ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_VERSION_NUM, sc->cfg.mcode_version); |
633 | |
634 | /* |
635 | * If the PCI Configuration Command Register "Parity Error Response |
636 | * Control" Bit was clear (0), then set the microcode variable |
637 | * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode |
638 | * to ignore DMA parity errors. |
639 | */ |
640 | if (sc->cfg.control_flag & CONTROL_FLAG_IGNORE_PERR) { |
641 | ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_CONTROL_FLAG, word); |
642 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_CONTROL_FLAG, |
643 | word | CONTROL_FLAG_IGNORE_PERR); |
644 | } |
645 | |
646 | switch (sc->chip_type) { |
647 | case ADW_CHIP_ASC3550: |
648 | /* |
649 | * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a |
650 | * FIFO threshold of 128 bytes. |
651 | * This register is only accessible to the host. |
652 | */ |
653 | ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_DMA_CFG0, |
654 | START_CTL_EMFU | READ_CMD_MRM); |
655 | break; |
656 | |
657 | case ADW_CHIP_ASC38C0800: |
658 | /* |
659 | * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register. |
660 | * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current |
661 | * cable detection and then we are able to read C_DET[3:0]. |
662 | * |
663 | * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1 |
664 | * Microcode Default Value' section below. |
665 | */ |
666 | ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_SCSI_CFG1, |
667 | ADW_READ_WORD_REGISTER(iot, ioh, IOPW_SCSI_CFG1) |
668 | | ADW_DIS_TERM_DRV); |
669 | |
670 | /* |
671 | * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and |
672 | * START_CTL_TH [3:2] bits for the default FIFO threshold. |
673 | * |
674 | * Note: ASC-38C0800 FIFO threshold has been changed to |
675 | * 256 bytes. |
676 | * |
677 | * For DMA Errata #4 set the BC_THRESH_ENB bit. |
678 | */ |
679 | ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_DMA_CFG0, |
680 | BC_THRESH_ENB | FIFO_THRESH_80B |
681 | | START_CTL_TH | READ_CMD_MRM); |
682 | break; |
683 | |
684 | case ADW_CHIP_ASC38C1600: |
685 | /* |
686 | * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register. |
687 | * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current |
688 | * cable detection and then we are able to read C_DET[3:0]. |
689 | * |
690 | * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1 |
691 | * Microcode Default Value' section below. |
692 | */ |
693 | ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_SCSI_CFG1, |
694 | ADW_READ_WORD_REGISTER(iot, ioh, IOPW_SCSI_CFG1) |
695 | | ADW_DIS_TERM_DRV); |
696 | |
697 | /* |
698 | * If the BIOS control flag AIPP (Asynchronous Information |
699 | * Phase Protection) disable bit is not set, then set the |
700 | * firmware 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to |
701 | * enable AIPP checking and encoding. |
702 | */ |
703 | if ((sc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0) { |
704 | ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_CONTROL_FLAG, word); |
705 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_CONTROL_FLAG, |
706 | word | CONTROL_FLAG_ENABLE_AIPP); |
707 | } |
708 | |
709 | /* |
710 | * For ASC-38C1600 use DMA_CFG0 default values: |
711 | * FIFO_THRESH_80B [6:4], and START_CTL_TH [3:2]. |
712 | */ |
713 | ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_DMA_CFG0, |
714 | FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM); |
715 | break; |
716 | } |
717 | |
718 | /* |
719 | * Microcode operating variables for WDTR, SDTR, and command tag |
720 | * queuing will be set in AdvInquiryHandling() based on what a |
721 | * device reports it is capable of in Inquiry byte 7. |
722 | * |
723 | * If SCSI Bus Resets have been disabled, then directly set |
724 | * SDTR and WDTR from the EEPROM configuration. This will allow |
725 | * the BIOS and warm boot to work without a SCSI bus hang on |
726 | * the Inquiry caused by host and target mismatched DTR values. |
727 | * Without the SCSI Bus Reset, before an Inquiry a device can't |
728 | * be assumed to be in Asynchronous, Narrow mode. |
729 | */ |
730 | if ((sc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) { |
731 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_WDTR_ABLE, sc->wdtr_able); |
732 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_SDTR_ABLE, sc->sdtr_able); |
733 | } |
734 | |
735 | /* |
736 | * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2, |
737 | * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID |
738 | * bitmask. These values determine the maximum SDTR speed negotiated |
739 | * with a device. |
740 | * |
741 | * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2, |
742 | * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them |
743 | * without determining here whether the device supports SDTR. |
744 | */ |
745 | switch (sc->chip_type) { |
746 | case ADW_CHIP_ASC3550: |
747 | word = 0; |
748 | for (tid = 0; tid <= ADW_MAX_TID; tid++) { |
749 | if (ADW_TID_TO_TIDMASK(tid) & sc->ultra_able) { |
750 | /* Set Ultra speed for TID 'tid'. */ |
751 | word |= (0x3 << (4 * (tid % 4))); |
752 | } else { |
753 | /* Set Fast speed for TID 'tid'. */ |
754 | word |= (0x2 << (4 * (tid % 4))); |
755 | } |
756 | /* Check if done with sdtr_speed1. */ |
757 | if (tid == 3) { |
758 | ADW_WRITE_WORD_LRAM(iot, ioh, |
759 | ADW_MC_SDTR_SPEED1, word); |
760 | word = 0; |
761 | /* Check if done with sdtr_speed2. */ |
762 | } else if (tid == 7) { |
763 | ADW_WRITE_WORD_LRAM(iot, ioh, |
764 | ADW_MC_SDTR_SPEED2, word); |
765 | word = 0; |
766 | /* Check if done with sdtr_speed3. */ |
767 | } else if (tid == 11) { |
768 | ADW_WRITE_WORD_LRAM(iot, ioh, |
769 | ADW_MC_SDTR_SPEED3, word); |
770 | word = 0; |
771 | /* Check if done with sdtr_speed4. */ |
772 | } else if (tid == 15) { |
773 | ADW_WRITE_WORD_LRAM(iot, ioh, |
774 | ADW_MC_SDTR_SPEED4, word); |
775 | /* End of loop. */ |
776 | } |
777 | } |
778 | |
779 | /* |
780 | * Set microcode operating variable for the |
781 | * disconnect per TID bitmask. |
782 | */ |
783 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_DISC_ENABLE, |
784 | sc->cfg.disc_enable); |
785 | break; |
786 | |
787 | case ADW_CHIP_ASC38C0800: |
788 | /* FALLTHROUGH */ |
789 | case ADW_CHIP_ASC38C1600: |
790 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_DISC_ENABLE, |
791 | sc->cfg.disc_enable); |
792 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_SDTR_SPEED1, |
793 | sc->sdtr_speed1); |
794 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_SDTR_SPEED2, |
795 | sc->sdtr_speed2); |
796 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_SDTR_SPEED3, |
797 | sc->sdtr_speed3); |
798 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_SDTR_SPEED4, |
799 | sc->sdtr_speed4); |
800 | break; |
801 | } |
802 | |
803 | |
804 | /* |
805 | * Set SCSI_CFG0 Microcode Default Value. |
806 | * |
807 | * The microcode will set the SCSI_CFG0 register using this value |
808 | * after it is started below. |
809 | */ |
810 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_DEFAULT_SCSI_CFG0, |
811 | ADW_PARITY_EN | ADW_QUEUE_128 | ADW_SEL_TMO_LONG | |
812 | ADW_OUR_ID_EN | sc->chip_scsi_id); |
813 | |
814 | |
815 | switch(sc->chip_type) { |
816 | case ADW_CHIP_ASC3550: |
817 | error_code = AdwASC3550Cabling(iot, ioh, &sc->cfg); |
818 | break; |
819 | |
820 | case ADW_CHIP_ASC38C0800: |
821 | error_code = AdwASC38C0800Cabling(iot, ioh, &sc->cfg); |
822 | break; |
823 | |
824 | case ADW_CHIP_ASC38C1600: |
825 | error_code = AdwASC38C1600Cabling(iot, ioh, &sc->cfg); |
826 | break; |
827 | } |
828 | if(error_code) { |
829 | return error_code; |
830 | } |
831 | |
832 | /* |
833 | * Set SEL_MASK Microcode Default Value |
834 | * |
835 | * The microcode will set the SEL_MASK register using this value |
836 | * after it is started below. |
837 | */ |
838 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_DEFAULT_SEL_MASK, |
839 | ADW_TID_TO_TIDMASK(sc->chip_scsi_id)); |
840 | |
841 | /* |
842 | * Create and Initialize Host->RISC Carrier lists |
843 | */ |
844 | sc->carr_freelist = AdwInitCarriers(sc->sc_dmamap_carrier, |
845 | sc->sc_control->carriers); |
846 | |
847 | /* |
848 | * Set-up the Host->RISC Initiator Command Queue (ICQ). |
849 | */ |
850 | |
851 | if ((sc->icq_sp = sc->carr_freelist) == NULL) { |
852 | return ADW_IERR_NO_CARRIER; |
853 | } |
854 | sc->carr_freelist = ADW_CARRIER_VADDR(sc, |
855 | ASC_GET_CARRP(sc->icq_sp->next_ba)); |
856 | |
857 | /* |
858 | * The first command issued will be placed in the stopper carrier. |
859 | */ |
860 | sc->icq_sp->next_ba = htole32(ASC_CQ_STOPPER); |
861 | |
862 | /* |
863 | * Set RISC ICQ physical address start value. |
864 | */ |
865 | ADW_WRITE_DWORD_LRAM(iot, ioh, ADW_MC_ICQ, le32toh(sc->icq_sp->carr_ba)); |
866 | |
867 | /* |
868 | * Initialize the COMMA register to the same value otherwise |
869 | * the RISC will prematurely detect a command is available. |
870 | */ |
871 | if(sc->chip_type == ADW_CHIP_ASC38C1600) { |
872 | ADW_WRITE_DWORD_REGISTER(iot, ioh, IOPDW_COMMA, |
873 | le32toh(sc->icq_sp->carr_ba)); |
874 | } |
875 | |
876 | /* |
877 | * Set-up the RISC->Host Initiator Response Queue (IRQ). |
878 | */ |
879 | if ((sc->irq_sp = sc->carr_freelist) == NULL) { |
880 | return ADW_IERR_NO_CARRIER; |
881 | } |
882 | sc->carr_freelist = ADW_CARRIER_VADDR(sc, |
883 | ASC_GET_CARRP(sc->irq_sp->next_ba)); |
884 | |
885 | /* |
886 | * The first command completed by the RISC will be placed in |
887 | * the stopper. |
888 | * |
889 | * Note: Set 'next_ba' to ASC_CQ_STOPPER. When the request is |
890 | * completed the RISC will set the ASC_RQ_DONE bit. |
891 | */ |
892 | sc->irq_sp->next_ba = htole32(ASC_CQ_STOPPER); |
893 | |
894 | /* |
895 | * Set RISC IRQ physical address start value. |
896 | */ |
897 | ADW_WRITE_DWORD_LRAM(iot, ioh, ADW_MC_IRQ, le32toh(sc->irq_sp->carr_ba)); |
898 | sc->carr_pending_cnt = 0; |
899 | |
900 | ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_INTR_ENABLES, |
901 | (ADW_INTR_ENABLE_HOST_INTR | ADW_INTR_ENABLE_GLOBAL_INTR)); |
902 | ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_CODE_BEGIN_ADDR, word); |
903 | ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_PC, word); |
904 | |
905 | /* finally, finally, gentlemen, start your engine */ |
906 | ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_RISC_CSR, ADW_RISC_CSR_RUN); |
907 | |
908 | /* |
909 | * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus |
910 | * Resets should be performed. The RISC has to be running |
911 | * to issue a SCSI Bus Reset. |
912 | */ |
913 | if (sc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) |
914 | { |
915 | /* |
916 | * If the BIOS Signature is present in memory, restore the |
917 | * BIOS Handshake Configuration Table and do not perform |
918 | * a SCSI Bus Reset. |
919 | */ |
920 | if (bios_mem[(ADW_MC_BIOS_SIGNATURE - ADW_MC_BIOSMEM)/2] == |
921 | 0x55AA) { |
922 | /* |
923 | * Restore per TID negotiated values. |
924 | */ |
925 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_WDTR_ABLE, |
926 | wdtr_able); |
927 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_SDTR_ABLE, |
928 | sdtr_able); |
929 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_TAGQNG_ABLE, |
930 | tagqng_able); |
931 | for (tid = 0; tid <= ADW_MAX_TID; tid++) { |
932 | ADW_WRITE_BYTE_LRAM(iot, ioh, |
933 | ADW_MC_NUMBER_OF_MAX_CMD + tid, |
934 | max_cmd[tid]); |
935 | } |
936 | } else { |
937 | if (AdwResetCCB(sc) != ADW_TRUE) { |
938 | error_code = ADW_WARN_BUSRESET_ERROR; |
939 | } |
940 | } |
941 | } |
942 | |
943 | return error_code; |
944 | } |
945 | |
946 | |
947 | int |
948 | AdwRamSelfTest(bus_space_tag_t iot, bus_space_handle_t ioh, u_int8_t chip_type) |
949 | { |
950 | int i; |
951 | u_int8_t byte; |
952 | |
953 | |
954 | if ((chip_type == ADW_CHIP_ASC38C0800) || |
955 | (chip_type == ADW_CHIP_ASC38C1600)) { |
956 | /* |
957 | * RAM BIST (RAM Built-In Self Test) |
958 | * |
959 | * Address : I/O base + offset 0x38h register (byte). |
960 | * Function: Bit 7-6(RW) : RAM mode |
961 | * Normal Mode : 0x00 |
962 | * Pre-test Mode : 0x40 |
963 | * RAM Test Mode : 0x80 |
964 | * Bit 5 : unused |
965 | * Bit 4(RO) : Done bit |
966 | * Bit 3-0(RO) : Status |
967 | * Host Error : 0x08 |
968 | * Int_RAM Error : 0x04 |
969 | * RISC Error : 0x02 |
970 | * SCSI Error : 0x01 |
971 | * No Error : 0x00 |
972 | * |
973 | * Note: RAM BIST code should be put right here, before loading |
974 | * the microcode and after saving the RISC memory BIOS region. |
975 | */ |
976 | |
977 | /* |
978 | * LRAM Pre-test |
979 | * |
980 | * Write PRE_TEST_MODE (0x40) to register and wait for |
981 | * 10 milliseconds. |
982 | * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), |
983 | * return an error. Reset to NORMAL_MODE (0x00) and do again. |
984 | * If cannot reset to NORMAL_MODE, return an error too. |
985 | */ |
986 | for (i = 0; i < 2; i++) { |
987 | ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_RAM_BIST, |
988 | PRE_TEST_MODE); |
989 | /* Wait for 10ms before reading back. */ |
990 | AdwSleepMilliSecond(10); |
991 | byte = ADW_READ_BYTE_REGISTER(iot, ioh, IOPB_RAM_BIST); |
992 | if ((byte & RAM_TEST_DONE) == 0 || (byte & 0x0F) != |
993 | PRE_TEST_VALUE) { |
994 | return ADW_IERR_BIST_PRE_TEST; |
995 | } |
996 | |
997 | ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_RAM_BIST, |
998 | NORMAL_MODE); |
999 | /* Wait for 10ms before reading back. */ |
1000 | AdwSleepMilliSecond(10); |
1001 | if (ADW_READ_BYTE_REGISTER(iot, ioh, IOPB_RAM_BIST) |
1002 | != NORMAL_VALUE) { |
1003 | return ADW_IERR_BIST_PRE_TEST; |
1004 | } |
1005 | } |
1006 | |
1007 | /* |
1008 | * LRAM Test - It takes about 1.5 ms to run through the test. |
1009 | * |
1010 | * Write RAM_TEST_MODE (0x80) to register and wait for |
1011 | * 10 milliseconds. |
1012 | * If Done bit not set or Status not 0, save register byte, |
1013 | * set the err_code, and return an error. |
1014 | */ |
1015 | ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_RAM_BIST, RAM_TEST_MODE); |
1016 | /* Wait for 10ms before checking status. */ |
1017 | AdwSleepMilliSecond(10); |
1018 | |
1019 | byte = ADW_READ_BYTE_REGISTER(iot, ioh, IOPB_RAM_BIST); |
1020 | if ((byte & RAM_TEST_DONE)==0 || (byte & RAM_TEST_STATUS)!=0) { |
1021 | /* Get here if Done bit not set or Status not 0. */ |
1022 | return ADW_IERR_BIST_RAM_TEST; |
1023 | } |
1024 | |
1025 | /* We need to reset back to normal mode after LRAM test passes*/ |
1026 | ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_RAM_BIST, NORMAL_MODE); |
1027 | } |
1028 | |
1029 | return 0; |
1030 | } |
1031 | |
1032 | |
1033 | int |
1034 | AdwLoadMCode(bus_space_tag_t iot, bus_space_handle_t ioh, u_int16_t *bios_mem, u_int8_t chip_type) |
1035 | { |
1036 | const u_int8_t *mcode_data; |
1037 | u_int32_t mcode_chksum; |
1038 | u_int16_t mcode_size; |
1039 | u_int32_t sum; |
1040 | u_int16_t code_sum; |
1041 | int begin_addr; |
1042 | int end_addr; |
1043 | int word; |
1044 | int adw_memsize; |
1045 | int adw_mcode_expanded_size; |
1046 | int i, j; |
1047 | |
1048 | |
1049 | switch(chip_type) { |
1050 | case ADW_CHIP_ASC3550: |
1051 | mcode_data = (const u_int8_t *)adw_asc3550_mcode_data.mcode_data; |
1052 | mcode_chksum = (u_int32_t)adw_asc3550_mcode_data.mcode_chksum; |
1053 | mcode_size = (u_int16_t)adw_asc3550_mcode_data.mcode_size; |
1054 | adw_memsize = ADW_3550_MEMSIZE; |
1055 | break; |
1056 | |
1057 | case ADW_CHIP_ASC38C0800: |
1058 | mcode_data = (const u_int8_t *)adw_asc38C0800_mcode_data.mcode_data; |
1059 | mcode_chksum =(u_int32_t)adw_asc38C0800_mcode_data.mcode_chksum; |
1060 | mcode_size = (u_int16_t)adw_asc38C0800_mcode_data.mcode_size; |
1061 | adw_memsize = ADW_38C0800_MEMSIZE; |
1062 | break; |
1063 | |
1064 | case ADW_CHIP_ASC38C1600: |
1065 | mcode_data = (const u_int8_t *)adw_asc38C1600_mcode_data.mcode_data; |
1066 | mcode_chksum =(u_int32_t)adw_asc38C1600_mcode_data.mcode_chksum; |
1067 | mcode_size = (u_int16_t)adw_asc38C1600_mcode_data.mcode_size; |
1068 | adw_memsize = ADW_38C1600_MEMSIZE; |
1069 | break; |
1070 | |
1071 | default: |
1072 | return (EINVAL); |
1073 | } |
1074 | |
1075 | /* |
1076 | * Write the microcode image to RISC memory starting at address 0. |
1077 | */ |
1078 | ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_RAM_ADDR, 0); |
1079 | |
1080 | /* Assume the following compressed format of the microcode buffer: |
1081 | * |
1082 | * 254 word (508 byte) table indexed by byte code followed |
1083 | * by the following byte codes: |
1084 | * |
1085 | * 1-Byte Code: |
1086 | * 00: Emit word 0 in table. |
1087 | * 01: Emit word 1 in table. |
1088 | * . |
1089 | * FD: Emit word 253 in table. |
1090 | * |
1091 | * Multi-Byte Code: |
1092 | * FE WW WW: (3 byte code) Word to emit is the next word WW WW. |
1093 | * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW. |
1094 | */ |
1095 | word = 0; |
1096 | for (i = 253 * 2; i < mcode_size; i++) { |
1097 | if (mcode_data[i] == 0xff) { |
1098 | for (j = 0; j < mcode_data[i + 1]; j++) { |
1099 | ADW_WRITE_WORD_AUTO_INC_LRAM(iot, ioh, |
1100 | (((u_int16_t)mcode_data[i + 3] << 8) | |
1101 | mcode_data[i + 2])); |
1102 | word++; |
1103 | } |
1104 | i += 3; |
1105 | } else if (mcode_data[i] == 0xfe) { |
1106 | ADW_WRITE_WORD_AUTO_INC_LRAM(iot, ioh, |
1107 | (((u_int16_t)mcode_data[i + 2] << 8) | |
1108 | mcode_data[i + 1])); |
1109 | i += 2; |
1110 | word++; |
1111 | } else { |
1112 | ADW_WRITE_WORD_AUTO_INC_LRAM(iot, ioh, (((u_int16_t) |
1113 | mcode_data[(mcode_data[i] * 2) + 1] <<8) | |
1114 | mcode_data[mcode_data[i] * 2])); |
1115 | word++; |
1116 | } |
1117 | } |
1118 | |
1119 | /* |
1120 | * Set 'word' for later use to clear the rest of memory and save |
1121 | * the expanded mcode size. |
1122 | */ |
1123 | word *= 2; |
1124 | adw_mcode_expanded_size = word; |
1125 | |
1126 | /* |
1127 | * Clear the rest of the Internal RAM. |
1128 | */ |
1129 | for (; word < adw_memsize; word += 2) { |
1130 | ADW_WRITE_WORD_AUTO_INC_LRAM(iot, ioh, 0); |
1131 | } |
1132 | |
1133 | /* |
1134 | * Verify the microcode checksum. |
1135 | */ |
1136 | sum = 0; |
1137 | ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_RAM_ADDR, 0); |
1138 | |
1139 | for (word = 0; word < adw_mcode_expanded_size; word += 2) { |
1140 | sum += ADW_READ_WORD_AUTO_INC_LRAM(iot, ioh); |
1141 | } |
1142 | |
1143 | if (sum != mcode_chksum) { |
1144 | return ADW_IERR_MCODE_CHKSUM; |
1145 | } |
1146 | |
1147 | /* |
1148 | * Restore the RISC memory BIOS region. |
1149 | */ |
1150 | for (i = 0; i < ADW_MC_BIOSLEN/2; i++) { |
1151 | if(chip_type == ADW_CHIP_ASC3550) { |
1152 | ADW_WRITE_BYTE_LRAM(iot, ioh, ADW_MC_BIOSMEM + (2 * i), |
1153 | bios_mem[i]); |
1154 | } else { |
1155 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_BIOSMEM + (2 * i), |
1156 | bios_mem[i]); |
1157 | } |
1158 | } |
1159 | |
1160 | /* |
1161 | * Calculate and write the microcode code checksum to the microcode |
1162 | * code checksum location ADW_MC_CODE_CHK_SUM (0x2C). |
1163 | */ |
1164 | ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_CODE_BEGIN_ADDR, begin_addr); |
1165 | ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_CODE_END_ADDR, end_addr); |
1166 | code_sum = 0; |
1167 | ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_RAM_ADDR, begin_addr); |
1168 | for (word = begin_addr; word < end_addr; word += 2) { |
1169 | code_sum += ADW_READ_WORD_AUTO_INC_LRAM(iot, ioh); |
1170 | } |
1171 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_CODE_CHK_SUM, code_sum); |
1172 | |
1173 | /* |
1174 | * Set the chip type. |
1175 | */ |
1176 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_CHIP_TYPE, chip_type); |
1177 | |
1178 | return 0; |
1179 | } |
1180 | |
1181 | |
1182 | int |
1183 | AdwASC3550Cabling(bus_space_tag_t iot, bus_space_handle_t ioh, ADW_DVC_CFG *cfg) |
1184 | { |
1185 | u_int16_t scsi_cfg1; |
1186 | |
1187 | |
1188 | /* |
1189 | * Determine SCSI_CFG1 Microcode Default Value. |
1190 | * |
1191 | * The microcode will set the SCSI_CFG1 register using this value |
1192 | * after it is started below. |
1193 | */ |
1194 | |
1195 | /* Read current SCSI_CFG1 Register value. */ |
1196 | scsi_cfg1 = ADW_READ_WORD_REGISTER(iot, ioh, IOPW_SCSI_CFG1); |
1197 | |
1198 | /* |
1199 | * If all three connectors are in use in ASC3550, return an error. |
1200 | */ |
1201 | if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 || |
1202 | (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) { |
1203 | return ADW_IERR_ILLEGAL_CONNECTION; |
1204 | } |
1205 | |
1206 | /* |
1207 | * If the cable is reversed all of the SCSI_CTRL register signals |
1208 | * will be set. Check for and return an error if this condition is |
1209 | * found. |
1210 | */ |
1211 | if ((ADW_READ_WORD_REGISTER(iot,ioh, IOPW_SCSI_CTRL) & 0x3F07)==0x3F07){ |
1212 | return ADW_IERR_REVERSED_CABLE; |
1213 | } |
1214 | |
1215 | /* |
1216 | * If this is a differential board and a single-ended device |
1217 | * is attached to one of the connectors, return an error. |
1218 | */ |
1219 | if ((scsi_cfg1 & ADW_DIFF_MODE) && |
1220 | (scsi_cfg1 & ADW_DIFF_SENSE) == 0) { |
1221 | return ADW_IERR_SINGLE_END_DEVICE; |
1222 | } |
1223 | |
1224 | /* |
1225 | * If automatic termination control is enabled, then set the |
1226 | * termination value based on a table listed in a_condor.h. |
1227 | * |
1228 | * If manual termination was specified with an EEPROM setting |
1229 | * then 'termination' was set-up in AdwInitFromEEPROM() and |
1230 | * is ready to be 'ored' into SCSI_CFG1. |
1231 | */ |
1232 | if (cfg->termination == 0) { |
1233 | /* |
1234 | * The software always controls termination by setting |
1235 | * TERM_CTL_SEL. |
1236 | * If TERM_CTL_SEL were set to 0, the hardware would set |
1237 | * termination. |
1238 | */ |
1239 | cfg->termination |= ADW_TERM_CTL_SEL; |
1240 | |
1241 | switch(scsi_cfg1 & ADW_CABLE_DETECT) { |
1242 | /* TERM_CTL_H: on, TERM_CTL_L: on */ |
1243 | case 0x3: case 0x7: case 0xB: |
1244 | case 0xD: case 0xE: case 0xF: |
1245 | cfg->termination |= |
1246 | (ADW_TERM_CTL_H | ADW_TERM_CTL_L); |
1247 | break; |
1248 | |
1249 | /* TERM_CTL_H: on, TERM_CTL_L: off */ |
1250 | case 0x1: case 0x5: case 0x9: |
1251 | case 0xA: case 0xC: |
1252 | cfg->termination |= ADW_TERM_CTL_H; |
1253 | break; |
1254 | |
1255 | /* TERM_CTL_H: off, TERM_CTL_L: off */ |
1256 | case 0x2: case 0x6: |
1257 | break; |
1258 | } |
1259 | } |
1260 | |
1261 | /* |
1262 | * Clear any set TERM_CTL_H and TERM_CTL_L bits. |
1263 | */ |
1264 | scsi_cfg1 &= ~ADW_TERM_CTL; |
1265 | |
1266 | /* |
1267 | * Invert the TERM_CTL_H and TERM_CTL_L bits and then |
1268 | * set 'scsi_cfg1'. The TERM_POL bit does not need to be |
1269 | * referenced, because the hardware internally inverts |
1270 | * the Termination High and Low bits if TERM_POL is set. |
1271 | */ |
1272 | scsi_cfg1 |= (ADW_TERM_CTL_SEL | (~cfg->termination & ADW_TERM_CTL)); |
1273 | |
1274 | /* |
1275 | * Set SCSI_CFG1 Microcode Default Value |
1276 | * |
1277 | * Set filter value and possibly modified termination control |
1278 | * bits in the Microcode SCSI_CFG1 Register Value. |
1279 | * |
1280 | * The microcode will set the SCSI_CFG1 register using this value |
1281 | * after it is started below. |
1282 | */ |
1283 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_DEFAULT_SCSI_CFG1, |
1284 | ADW_FLTR_DISABLE | scsi_cfg1); |
1285 | |
1286 | /* |
1287 | * Set MEM_CFG Microcode Default Value |
1288 | * |
1289 | * The microcode will set the MEM_CFG register using this value |
1290 | * after it is started below. |
1291 | * |
1292 | * MEM_CFG may be accessed as a word or byte, but only bits 0-7 |
1293 | * are defined. |
1294 | * |
1295 | * ASC-3550 has 8KB internal memory. |
1296 | */ |
1297 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_DEFAULT_MEM_CFG, |
1298 | ADW_BIOS_EN | ADW_RAM_SZ_8KB); |
1299 | |
1300 | return 0; |
1301 | } |
1302 | |
1303 | |
1304 | int |
1305 | AdwASC38C0800Cabling(bus_space_tag_t iot, bus_space_handle_t ioh, ADW_DVC_CFG *cfg) |
1306 | { |
1307 | u_int16_t scsi_cfg1; |
1308 | |
1309 | |
1310 | /* |
1311 | * Determine SCSI_CFG1 Microcode Default Value. |
1312 | * |
1313 | * The microcode will set the SCSI_CFG1 register using this value |
1314 | * after it is started below. |
1315 | */ |
1316 | |
1317 | /* Read current SCSI_CFG1 Register value. */ |
1318 | scsi_cfg1 = ADW_READ_WORD_REGISTER(iot, ioh, IOPW_SCSI_CFG1); |
1319 | |
1320 | /* |
1321 | * If the cable is reversed all of the SCSI_CTRL register signals |
1322 | * will be set. Check for and return an error if this condition is |
1323 | * found. |
1324 | */ |
1325 | if ((ADW_READ_WORD_REGISTER(iot,ioh, IOPW_SCSI_CTRL) & 0x3F07)==0x3F07){ |
1326 | return ADW_IERR_REVERSED_CABLE; |
1327 | } |
1328 | |
1329 | /* |
1330 | * All kind of combinations of devices attached to one of four |
1331 | * connectors are acceptable except HVD device attached. |
1332 | * For example, LVD device can be attached to SE connector while |
1333 | * SE device attached to LVD connector. |
1334 | * If LVD device attached to SE connector, it only runs up to |
1335 | * Ultra speed. |
1336 | * |
1337 | * If an HVD device is attached to one of LVD connectors, return |
1338 | * an error. |
1339 | * However, there is no way to detect HVD device attached to |
1340 | * SE connectors. |
1341 | */ |
1342 | if (scsi_cfg1 & ADW_HVD) { |
1343 | return ADW_IERR_HVD_DEVICE; |
1344 | } |
1345 | |
1346 | /* |
1347 | * If either SE or LVD automatic termination control is enabled, then |
1348 | * set the termination value based on a table listed in a_condor.h. |
1349 | * |
1350 | * If manual termination was specified with an EEPROM setting then |
1351 | * 'termination' was set-up in AdwInitFromEEPROM() and is ready |
1352 | * to be 'ored' into SCSI_CFG1. |
1353 | */ |
1354 | if ((cfg->termination & ADW_TERM_SE) == 0) { |
1355 | /* SE automatic termination control is enabled. */ |
1356 | switch(scsi_cfg1 & ADW_C_DET_SE) { |
1357 | /* TERM_SE_HI: on, TERM_SE_LO: on */ |
1358 | case 0x1: case 0x2: case 0x3: |
1359 | cfg->termination |= ADW_TERM_SE; |
1360 | break; |
1361 | |
1362 | /* TERM_SE_HI: on, TERM_SE_LO: off */ |
1363 | case 0x0: |
1364 | cfg->termination |= ADW_TERM_SE_HI; |
1365 | break; |
1366 | } |
1367 | } |
1368 | |
1369 | if ((cfg->termination & ADW_TERM_LVD) == 0) { |
1370 | /* LVD automatic termination control is enabled. */ |
1371 | switch(scsi_cfg1 & ADW_C_DET_LVD) { |
1372 | /* TERM_LVD_HI: on, TERM_LVD_LO: on */ |
1373 | case 0x4: case 0x8: case 0xC: |
1374 | cfg->termination |= ADW_TERM_LVD; |
1375 | break; |
1376 | |
1377 | /* TERM_LVD_HI: off, TERM_LVD_LO: off */ |
1378 | case 0x0: |
1379 | break; |
1380 | } |
1381 | } |
1382 | |
1383 | /* |
1384 | * Clear any set TERM_SE and TERM_LVD bits. |
1385 | */ |
1386 | scsi_cfg1 &= (~ADW_TERM_SE & ~ADW_TERM_LVD); |
1387 | |
1388 | /* |
1389 | * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'. |
1390 | */ |
1391 | scsi_cfg1 |= (~cfg->termination & 0xF0); |
1392 | |
1393 | /* |
1394 | * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and |
1395 | * HVD/LVD/SE bits and set possibly modified termination control bits |
1396 | * in the Microcode SCSI_CFG1 Register Value. |
1397 | */ |
1398 | scsi_cfg1 &= (~ADW_BIG_ENDIAN & ~ADW_DIS_TERM_DRV & |
1399 | ~ADW_TERM_POL & ~ADW_HVD_LVD_SE); |
1400 | |
1401 | /* |
1402 | * Set SCSI_CFG1 Microcode Default Value |
1403 | * |
1404 | * Set possibly modified termination control and reset DIS_TERM_DRV |
1405 | * bits in the Microcode SCSI_CFG1 Register Value. |
1406 | * |
1407 | * The microcode will set the SCSI_CFG1 register using this value |
1408 | * after it is started below. |
1409 | */ |
1410 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_DEFAULT_SCSI_CFG1, scsi_cfg1); |
1411 | |
1412 | /* |
1413 | * Set MEM_CFG Microcode Default Value |
1414 | * |
1415 | * The microcode will set the MEM_CFG register using this value |
1416 | * after it is started below. |
1417 | * |
1418 | * MEM_CFG may be accessed as a word or byte, but only bits 0-7 |
1419 | * are defined. |
1420 | * |
1421 | * ASC-38C0800 has 16KB internal memory. |
1422 | */ |
1423 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_DEFAULT_MEM_CFG, |
1424 | ADW_BIOS_EN | ADW_RAM_SZ_16KB); |
1425 | |
1426 | return 0; |
1427 | } |
1428 | |
1429 | |
1430 | int |
1431 | AdwASC38C1600Cabling(bus_space_tag_t iot, bus_space_handle_t ioh, ADW_DVC_CFG *cfg) |
1432 | { |
1433 | u_int16_t scsi_cfg1; |
1434 | |
1435 | |
1436 | /* |
1437 | * Determine SCSI_CFG1 Microcode Default Value. |
1438 | * |
1439 | * The microcode will set the SCSI_CFG1 register using this value |
1440 | * after it is started below. |
1441 | * Each ASC-38C1600 function has only two cable detect bits. |
1442 | * The bus mode override bits are in IOPB_SOFT_OVER_WR. |
1443 | */ |
1444 | |
1445 | /* Read current SCSI_CFG1 Register value. */ |
1446 | scsi_cfg1 = ADW_READ_WORD_REGISTER(iot, ioh, IOPW_SCSI_CFG1); |
1447 | |
1448 | /* |
1449 | * If the cable is reversed all of the SCSI_CTRL register signals |
1450 | * will be set. Check for and return an error if this condition is |
1451 | * found. |
1452 | */ |
1453 | if ((ADW_READ_WORD_REGISTER(iot,ioh, IOPW_SCSI_CTRL) & 0x3F07)==0x3F07){ |
1454 | return ADW_IERR_REVERSED_CABLE; |
1455 | } |
1456 | |
1457 | /* |
1458 | * Each ASC-38C1600 function has two connectors. Only an HVD device |
1459 | * cannot be connected to either connector. An LVD device or SE device |
1460 | * may be connected to either connector. If an SE device is connected, |
1461 | * then at most Ultra speed (20 MHz) can be used on both connectors. |
1462 | * |
1463 | * If an HVD device is attached, return an error. |
1464 | */ |
1465 | if (scsi_cfg1 & ADW_HVD) { |
1466 | return ADW_IERR_HVD_DEVICE; |
1467 | } |
1468 | |
1469 | /* |
1470 | * Each function in the ASC-38C1600 uses only the SE cable detect and |
1471 | * termination because there are two connectors for each function. |
1472 | * Each function may use either LVD or SE mode. |
1473 | * Corresponding the SE automatic termination control EEPROM bits are |
1474 | * used for each function. |
1475 | * Each function has its own EEPROM. If SE automatic control is enabled |
1476 | * for the function, then set the termination value based on a table |
1477 | * listed in adwlib.h. |
1478 | * |
1479 | * If manual termination is specified in the EEPROM for the function, |
1480 | * then 'termination' was set-up in AdwInitFromEEPROM() and is |
1481 | * ready to be 'ored' into SCSI_CFG1. |
1482 | */ |
1483 | if ((cfg->termination & ADW_TERM_SE) == 0) { |
1484 | /* SE automatic termination control is enabled. */ |
1485 | switch(scsi_cfg1 & ADW_C_DET_SE) { |
1486 | /* TERM_SE_HI: on, TERM_SE_LO: on */ |
1487 | case 0x1: case 0x2: case 0x3: |
1488 | cfg->termination |= ADW_TERM_SE; |
1489 | break; |
1490 | |
1491 | case 0x0: |
1492 | #if 0 |
1493 | /* !!!!TODO!!!! */ |
1494 | if (ASC_PCI_ID2FUNC(cfg->pci_slot_info) == 0) { |
1495 | /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */ |
1496 | } |
1497 | else |
1498 | #endif |
1499 | { |
1500 | /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */ |
1501 | cfg->termination |= ADW_TERM_SE_HI; |
1502 | } |
1503 | break; |
1504 | } |
1505 | } |
1506 | |
1507 | /* |
1508 | * Clear any set TERM_SE bits. |
1509 | */ |
1510 | scsi_cfg1 &= ~ADW_TERM_SE; |
1511 | |
1512 | /* |
1513 | * Invert the TERM_SE bits and then set 'scsi_cfg1'. |
1514 | */ |
1515 | scsi_cfg1 |= (~cfg->termination & ADW_TERM_SE); |
1516 | |
1517 | /* |
1518 | * Clear Big Endian and Terminator Polarity bits and set possibly |
1519 | * modified termination control bits in the Microcode SCSI_CFG1 |
1520 | * Register Value. |
1521 | */ |
1522 | scsi_cfg1 &= (~ADW_BIG_ENDIAN & ~ADW_DIS_TERM_DRV & ~ADW_TERM_POL); |
1523 | |
1524 | /* |
1525 | * Set SCSI_CFG1 Microcode Default Value |
1526 | * |
1527 | * Set possibly modified termination control bits in the Microcode |
1528 | * SCSI_CFG1 Register Value. |
1529 | * |
1530 | * The microcode will set the SCSI_CFG1 register using this value |
1531 | * after it is started below. |
1532 | */ |
1533 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_DEFAULT_SCSI_CFG1, scsi_cfg1); |
1534 | |
1535 | /* |
1536 | * Set MEM_CFG Microcode Default Value |
1537 | * |
1538 | * The microcode will set the MEM_CFG register using this value |
1539 | * after it is started below. |
1540 | * |
1541 | * MEM_CFG may be accessed as a word or byte, but only bits 0-7 |
1542 | * are defined. |
1543 | * |
1544 | * ASC-38C1600 has 32KB internal memory. |
1545 | */ |
1546 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_DEFAULT_MEM_CFG, |
1547 | ADW_BIOS_EN | ADW_RAM_SZ_32KB); |
1548 | |
1549 | return 0; |
1550 | } |
1551 | |
1552 | |
1553 | /* |
1554 | * Read EEPROM configuration into the specified buffer. |
1555 | * |
1556 | * Return a checksum based on the EEPROM configuration read. |
1557 | */ |
1558 | static u_int16_t |
1559 | AdwGetEEPROMConfig(bus_space_tag_t iot, bus_space_handle_t ioh, ADW_EEPROM *cfg_buf) |
1560 | { |
1561 | u_int16_t wval, chksum; |
1562 | u_int16_t *wbuf; |
1563 | int eep_addr; |
1564 | |
1565 | |
1566 | wbuf = (u_int16_t *) cfg_buf; |
1567 | chksum = 0; |
1568 | |
1569 | for (eep_addr = ASC_EEP_DVC_CFG_BEGIN; |
1570 | eep_addr < ASC_EEP_DVC_CFG_END; |
1571 | eep_addr++, wbuf++) { |
1572 | wval = AdwReadEEPWord(iot, ioh, eep_addr); |
1573 | chksum += wval; |
1574 | *wbuf = wval; |
1575 | } |
1576 | |
1577 | *wbuf = AdwReadEEPWord(iot, ioh, eep_addr); |
1578 | wbuf++; |
1579 | for (eep_addr = ASC_EEP_DVC_CTL_BEGIN; |
1580 | eep_addr < ASC_EEP_MAX_WORD_ADDR; |
1581 | eep_addr++, wbuf++) { |
1582 | *wbuf = AdwReadEEPWord(iot, ioh, eep_addr); |
1583 | } |
1584 | |
1585 | return chksum; |
1586 | } |
1587 | |
1588 | |
1589 | /* |
1590 | * Read the EEPROM from specified location |
1591 | */ |
1592 | static u_int16_t |
1593 | AdwReadEEPWord(bus_space_tag_t iot, bus_space_handle_t ioh, int eep_word_addr) |
1594 | { |
1595 | ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_EE_CMD, |
1596 | ASC_EEP_CMD_READ | eep_word_addr); |
1597 | AdwWaitEEPCmd(iot, ioh); |
1598 | |
1599 | return ADW_READ_WORD_REGISTER(iot, ioh, IOPW_EE_DATA); |
1600 | } |
1601 | |
1602 | |
1603 | /* |
1604 | * Wait for EEPROM command to complete |
1605 | */ |
1606 | static void |
1607 | AdwWaitEEPCmd(bus_space_tag_t iot, bus_space_handle_t ioh) |
1608 | { |
1609 | int eep_delay_ms; |
1610 | |
1611 | |
1612 | for (eep_delay_ms = 0; eep_delay_ms < ASC_EEP_DELAY_MS; eep_delay_ms++){ |
1613 | if (ADW_READ_WORD_REGISTER(iot, ioh, IOPW_EE_CMD) & |
1614 | ASC_EEP_CMD_DONE) { |
1615 | break; |
1616 | } |
1617 | AdwSleepMilliSecond(1); |
1618 | } |
1619 | |
1620 | (void)ADW_READ_WORD_REGISTER(iot, ioh, IOPW_EE_CMD); |
1621 | } |
1622 | |
1623 | |
1624 | /* |
1625 | * Write the EEPROM from 'cfg_buf'. |
1626 | */ |
1627 | static void |
1628 | AdwSetEEPROMConfig(bus_space_tag_t iot, bus_space_handle_t ioh, ADW_EEPROM *cfg_buf) |
1629 | { |
1630 | u_int16_t *wbuf; |
1631 | u_int16_t addr, chksum; |
1632 | |
1633 | |
1634 | wbuf = (u_int16_t *) cfg_buf; |
1635 | chksum = 0; |
1636 | |
1637 | ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE); |
1638 | AdwWaitEEPCmd(iot, ioh); |
1639 | |
1640 | /* |
1641 | * Write EEPROM from word 0 to word 20 |
1642 | */ |
1643 | for (addr = ASC_EEP_DVC_CFG_BEGIN; |
1644 | addr < ASC_EEP_DVC_CFG_END; addr++, wbuf++) { |
1645 | chksum += *wbuf; |
1646 | ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_EE_DATA, *wbuf); |
1647 | ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_EE_CMD, |
1648 | ASC_EEP_CMD_WRITE | addr); |
1649 | AdwWaitEEPCmd(iot, ioh); |
1650 | AdwSleepMilliSecond(ASC_EEP_DELAY_MS); |
1651 | } |
1652 | |
1653 | /* |
1654 | * Write EEPROM checksum at word 21 |
1655 | */ |
1656 | ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_EE_DATA, chksum); |
1657 | ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_EE_CMD, |
1658 | ASC_EEP_CMD_WRITE | addr); |
1659 | AdwWaitEEPCmd(iot, ioh); |
1660 | wbuf++; /* skip over check_sum */ |
1661 | |
1662 | /* |
1663 | * Write EEPROM OEM name at words 22 to 29 |
1664 | */ |
1665 | for (addr = ASC_EEP_DVC_CTL_BEGIN; |
1666 | addr < ASC_EEP_MAX_WORD_ADDR; addr++, wbuf++) { |
1667 | ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_EE_DATA, *wbuf); |
1668 | ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_EE_CMD, |
1669 | ASC_EEP_CMD_WRITE | addr); |
1670 | AdwWaitEEPCmd(iot, ioh); |
1671 | } |
1672 | |
1673 | ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_EE_CMD, |
1674 | ASC_EEP_CMD_WRITE_DISABLE); |
1675 | AdwWaitEEPCmd(iot, ioh); |
1676 | |
1677 | return; |
1678 | } |
1679 | |
1680 | |
1681 | /* |
1682 | * AdwExeScsiQueue() - Send a request to the RISC microcode program. |
1683 | * |
1684 | * Allocate a carrier structure, point the carrier to the ADW_SCSI_REQ_Q, |
1685 | * add the carrier to the ICQ (Initiator Command Queue), and tickle the |
1686 | * RISC to notify it a new command is ready to be executed. |
1687 | * |
1688 | * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be |
1689 | * set to SCSI_MAX_RETRY. |
1690 | * |
1691 | * Return: |
1692 | * ADW_SUCCESS(1) - The request was successfully queued. |
1693 | * ADW_BUSY(0) - Resource unavailable; Retry again after pending |
1694 | * request completes. |
1695 | * ADW_ERROR(-1) - Invalid ADW_SCSI_REQ_Q request structure |
1696 | * host IC error. |
1697 | */ |
1698 | int |
1699 | AdwExeScsiQueue(ADW_SOFTC *sc, ADW_SCSI_REQ_Q *scsiq) |
1700 | { |
1701 | bus_space_tag_t iot = sc->sc_iot; |
1702 | bus_space_handle_t ioh = sc->sc_ioh; |
1703 | ADW_CCB *ccb; |
1704 | u_int32_t req_paddr; |
1705 | ADW_CARRIER *new_carrp; |
1706 | |
1707 | /* |
1708 | * The ADW_SCSI_REQ_Q 'target_id' field should never exceed ADW_MAX_TID. |
1709 | */ |
1710 | if (scsiq->target_id > ADW_MAX_TID) { |
1711 | scsiq->host_status = QHSTA_M_INVALID_DEVICE; |
1712 | scsiq->done_status = QD_WITH_ERROR; |
1713 | return ADW_ERROR; |
1714 | } |
1715 | |
1716 | /* |
1717 | * Begin of CRITICAL SECTION: Must be protected within splbio/splx pair |
1718 | */ |
1719 | |
1720 | ccb = adw_ccb_phys_kv(sc, scsiq->ccb_ptr); |
1721 | |
1722 | /* |
1723 | * Allocate a carrier and initialize fields. |
1724 | */ |
1725 | if ((new_carrp = sc->carr_freelist) == NULL) { |
1726 | return ADW_BUSY; |
1727 | } |
1728 | sc->carr_freelist = ADW_CARRIER_VADDR(sc, |
1729 | ASC_GET_CARRP(new_carrp->next_ba)); |
1730 | sc->carr_pending_cnt++; |
1731 | |
1732 | /* |
1733 | * Set the carrier to be a stopper by setting 'next_ba' |
1734 | * to the stopper value. The current stopper will be changed |
1735 | * below to point to the new stopper. |
1736 | */ |
1737 | new_carrp->next_ba = htole32(ASC_CQ_STOPPER); |
1738 | |
1739 | req_paddr = sc->sc_dmamap_control->dm_segs[0].ds_addr + |
1740 | ADW_CCB_OFF(ccb) + offsetof(struct adw_ccb, scsiq); |
1741 | |
1742 | /* Save physical address of ADW_SCSI_REQ_Q and Carrier. */ |
1743 | scsiq->scsiq_rptr = htole32(req_paddr); |
1744 | |
1745 | /* |
1746 | * Every ADV_CARR_T.carr_ba is byte swapped to little-endian |
1747 | * order during initialization. |
1748 | */ |
1749 | scsiq->carr_ba = sc->icq_sp->carr_ba; |
1750 | scsiq->carr_va = sc->icq_sp->carr_ba; |
1751 | |
1752 | /* |
1753 | * Use the current stopper to send the ADW_SCSI_REQ_Q command to |
1754 | * the microcode. The newly allocated stopper will become the new |
1755 | * stopper. |
1756 | */ |
1757 | sc->icq_sp->areq_ba = htole32(req_paddr); |
1758 | |
1759 | /* |
1760 | * Set the 'next_ba' pointer for the old stopper to be the |
1761 | * physical address of the new stopper. The RISC can only |
1762 | * follow physical addresses. |
1763 | */ |
1764 | sc->icq_sp->next_ba = new_carrp->carr_ba; |
1765 | |
1766 | #if ADW_DEBUG |
1767 | printf("icq 0x%x, 0x%x, 0x%x, 0x%x\n" , |
1768 | sc->icq_sp->carr_id, |
1769 | sc->icq_sp->carr_ba, |
1770 | sc->icq_sp->areq_ba, |
1771 | sc->icq_sp->next_ba); |
1772 | #endif |
1773 | /* |
1774 | * Set the host adapter stopper pointer to point to the new carrier. |
1775 | */ |
1776 | sc->icq_sp = new_carrp; |
1777 | |
1778 | if (sc->chip_type == ADW_CHIP_ASC3550 || |
1779 | sc->chip_type == ADW_CHIP_ASC38C0800) { |
1780 | /* |
1781 | * Tickle the RISC to tell it to read its Command Queue Head |
1782 | * pointer. |
1783 | */ |
1784 | ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_TICKLE, ADW_TICKLE_A); |
1785 | if (sc->chip_type == ADW_CHIP_ASC3550) { |
1786 | /* |
1787 | * Clear the tickle value. In the ASC-3550 the RISC flag |
1788 | * command 'clr_tickle_a' does not work unless the host |
1789 | * value is cleared. |
1790 | */ |
1791 | ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_TICKLE, |
1792 | ADW_TICKLE_NOP); |
1793 | } |
1794 | } else if (sc->chip_type == ADW_CHIP_ASC38C1600) { |
1795 | /* |
1796 | * Notify the RISC a carrier is ready by writing the physical |
1797 | * address of the new carrier stopper to the COMMA register. |
1798 | */ |
1799 | ADW_WRITE_DWORD_REGISTER(iot, ioh, IOPDW_COMMA, |
1800 | le32toh(new_carrp->carr_ba)); |
1801 | } |
1802 | |
1803 | /* |
1804 | * End of CRITICAL SECTION: Must be protected within splbio/splx pair |
1805 | */ |
1806 | |
1807 | return ADW_SUCCESS; |
1808 | } |
1809 | |
1810 | |
1811 | void |
1812 | AdwResetChip(bus_space_tag_t iot, bus_space_handle_t ioh) |
1813 | { |
1814 | |
1815 | /* |
1816 | * Reset Chip. |
1817 | */ |
1818 | ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_CTRL_REG, |
1819 | ADW_CTRL_REG_CMD_RESET); |
1820 | AdwSleepMilliSecond(100); |
1821 | ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_CTRL_REG, |
1822 | ADW_CTRL_REG_CMD_WR_IO_REG); |
1823 | } |
1824 | |
1825 | |
1826 | /* |
1827 | * Reset SCSI Bus and purge all outstanding requests. |
1828 | * |
1829 | * Return Value: |
1830 | * ADW_TRUE(1) - All requests are purged and SCSI Bus is reset. |
1831 | * ADW_FALSE(0) - Microcode command failed. |
1832 | * ADW_ERROR(-1) - Microcode command timed-out. Microcode or IC |
1833 | * may be hung which requires driver recovery. |
1834 | */ |
1835 | int |
1836 | AdwResetCCB(ADW_SOFTC *sc) |
1837 | { |
1838 | int status; |
1839 | |
1840 | /* |
1841 | * Send the SCSI Bus Reset idle start idle command which asserts |
1842 | * the SCSI Bus Reset signal. |
1843 | */ |
1844 | status = AdwSendIdleCmd(sc, (u_int16_t) IDLE_CMD_SCSI_RESET_START, 0L); |
1845 | if (status != ADW_TRUE) { |
1846 | return status; |
1847 | } |
1848 | |
1849 | /* |
1850 | * Delay for the specified SCSI Bus Reset hold time. |
1851 | * |
1852 | * The hold time delay is done on the host because the RISC has no |
1853 | * microsecond accurate timer. |
1854 | */ |
1855 | AdwDelayMicroSecond((u_int16_t) ASC_SCSI_RESET_HOLD_TIME_US); |
1856 | |
1857 | /* |
1858 | * Send the SCSI Bus Reset end idle command which de-asserts |
1859 | * the SCSI Bus Reset signal and purges any pending requests. |
1860 | */ |
1861 | status = AdwSendIdleCmd(sc, (u_int16_t) IDLE_CMD_SCSI_RESET_END, 0L); |
1862 | if (status != ADW_TRUE) { |
1863 | return status; |
1864 | } |
1865 | |
1866 | AdwSleepMilliSecond((u_int32_t) sc->scsi_reset_wait * 1000); |
1867 | |
1868 | return status; |
1869 | } |
1870 | |
1871 | |
1872 | /* |
1873 | * Reset chip and SCSI Bus. |
1874 | * |
1875 | * Return Value: |
1876 | * ADW_TRUE(1) - Chip re-initialization and SCSI Bus Reset successful. |
1877 | * ADW_FALSE(0) - Chip re-initialization and SCSI Bus Reset failure. |
1878 | */ |
1879 | int |
1880 | AdwResetSCSIBus(ADW_SOFTC *sc) |
1881 | { |
1882 | bus_space_tag_t iot = sc->sc_iot; |
1883 | bus_space_handle_t ioh = sc->sc_ioh; |
1884 | int status; |
1885 | u_int16_t wdtr_able, sdtr_able, tagqng_able; |
1886 | u_int16_t ppr_able = 0; /* XXX: gcc */ |
1887 | u_int8_t tid, max_cmd[ADW_MAX_TID + 1]; |
1888 | u_int16_t bios_sig; |
1889 | |
1890 | |
1891 | /* |
1892 | * Save current per TID negotiated values. |
1893 | */ |
1894 | ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_WDTR_ABLE, wdtr_able); |
1895 | ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_SDTR_ABLE, sdtr_able); |
1896 | if (sc->chip_type == ADW_CHIP_ASC38C1600) { |
1897 | ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_PPR_ABLE, ppr_able); |
1898 | } |
1899 | ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_TAGQNG_ABLE, tagqng_able); |
1900 | for (tid = 0; tid <= ADW_MAX_TID; tid++) { |
1901 | ADW_READ_BYTE_LRAM(iot, ioh, ADW_MC_NUMBER_OF_MAX_CMD + tid, |
1902 | max_cmd[tid]); |
1903 | } |
1904 | |
1905 | /* |
1906 | * Force the AdwInitAscDriver() function to perform a SCSI Bus Reset |
1907 | * by clearing the BIOS signature word. |
1908 | * The initialization functions assumes a SCSI Bus Reset is not |
1909 | * needed if the BIOS signature word is present. |
1910 | */ |
1911 | ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_BIOS_SIGNATURE, bios_sig); |
1912 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_BIOS_SIGNATURE, 0); |
1913 | |
1914 | /* |
1915 | * Stop chip and reset it. |
1916 | */ |
1917 | ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_RISC_CSR, ADW_RISC_CSR_STOP); |
1918 | ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_CTRL_REG, |
1919 | ADW_CTRL_REG_CMD_RESET); |
1920 | AdwSleepMilliSecond(100); |
1921 | ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_CTRL_REG, |
1922 | ADW_CTRL_REG_CMD_WR_IO_REG); |
1923 | |
1924 | /* |
1925 | * Reset Adv Library error code, if any, and try |
1926 | * re-initializing the chip. |
1927 | * Then translate initialization return value to status value. |
1928 | */ |
1929 | status = (AdwInitDriver(sc) == 0)? ADW_TRUE : ADW_FALSE; |
1930 | |
1931 | /* |
1932 | * Restore the BIOS signature word. |
1933 | */ |
1934 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_BIOS_SIGNATURE, bios_sig); |
1935 | |
1936 | /* |
1937 | * Restore per TID negotiated values. |
1938 | */ |
1939 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_WDTR_ABLE, wdtr_able); |
1940 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_SDTR_ABLE, sdtr_able); |
1941 | if (sc->chip_type == ADW_CHIP_ASC38C1600) { |
1942 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_PPR_ABLE, ppr_able); |
1943 | } |
1944 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_TAGQNG_ABLE, tagqng_able); |
1945 | for (tid = 0; tid <= ADW_MAX_TID; tid++) { |
1946 | ADW_WRITE_BYTE_LRAM(iot, ioh, ADW_MC_NUMBER_OF_MAX_CMD + tid, |
1947 | max_cmd[tid]); |
1948 | } |
1949 | |
1950 | return status; |
1951 | } |
1952 | |
1953 | |
1954 | /* |
1955 | * Adv Library Interrupt Service Routine |
1956 | * |
1957 | * This function is called by a driver's interrupt service routine. |
1958 | * The function disables and re-enables interrupts. |
1959 | * |
1960 | * When a microcode idle command is completed, the ADV_DVC_VAR |
1961 | * 'idle_cmd_done' field is set to ADW_TRUE. |
1962 | * |
1963 | * Note: AdwISR() can be called when interrupts are disabled or even |
1964 | * when there is no hardware interrupt condition present. It will |
1965 | * always check for completed idle commands and microcode requests. |
1966 | * This is an important feature that shouldn't be changed because it |
1967 | * allows commands to be completed from polling mode loops. |
1968 | * |
1969 | * Return: |
1970 | * ADW_TRUE(1) - interrupt was pending |
1971 | * ADW_FALSE(0) - no interrupt was pending |
1972 | */ |
1973 | int |
1974 | AdwISR(ADW_SOFTC *sc) |
1975 | { |
1976 | bus_space_tag_t iot = sc->sc_iot; |
1977 | bus_space_handle_t ioh = sc->sc_ioh; |
1978 | u_int8_t int_stat; |
1979 | ADW_CARRIER *free_carrp/*, *ccb_carr*/; |
1980 | u_int32_t irq_next_pa; |
1981 | ADW_SCSI_REQ_Q *scsiq; |
1982 | ADW_CCB *ccb; |
1983 | int s; |
1984 | |
1985 | |
1986 | s = splbio(); |
1987 | |
1988 | /* Reading the register clears the interrupt. */ |
1989 | int_stat = ADW_READ_BYTE_REGISTER(iot, ioh, IOPB_INTR_STATUS_REG); |
1990 | |
1991 | if ((int_stat & (ADW_INTR_STATUS_INTRA | ADW_INTR_STATUS_INTRB | |
1992 | ADW_INTR_STATUS_INTRC)) == 0) { |
1993 | splx(s); |
1994 | return ADW_FALSE; |
1995 | } |
1996 | |
1997 | /* |
1998 | * Notify the driver of an asynchronous microcode condition by |
1999 | * calling the ADV_DVC_VAR.async_callback function. The function |
2000 | * is passed the microcode ADW_MC_INTRB_CODE byte value. |
2001 | */ |
2002 | if (int_stat & ADW_INTR_STATUS_INTRB) { |
2003 | u_int8_t intrb_code; |
2004 | |
2005 | ADW_READ_BYTE_LRAM(iot, ioh, ADW_MC_INTRB_CODE, intrb_code); |
2006 | |
2007 | if (sc->chip_type == ADW_CHIP_ASC3550 || |
2008 | sc->chip_type == ADW_CHIP_ASC38C0800) { |
2009 | if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE && |
2010 | sc->carr_pending_cnt != 0) { |
2011 | ADW_WRITE_BYTE_REGISTER(iot, ioh, |
2012 | IOPB_TICKLE, ADW_TICKLE_A); |
2013 | if (sc->chip_type == ADW_CHIP_ASC3550) { |
2014 | ADW_WRITE_BYTE_REGISTER(iot, ioh, |
2015 | IOPB_TICKLE, ADW_TICKLE_NOP); |
2016 | } |
2017 | } |
2018 | } |
2019 | |
2020 | if (sc->async_callback != 0) { |
2021 | (*(ADW_ASYNC_CALLBACK)sc->async_callback)(sc, intrb_code); |
2022 | } |
2023 | } |
2024 | |
2025 | /* |
2026 | * Check if the IRQ stopper carrier contains a completed request. |
2027 | */ |
2028 | while (((le32toh(irq_next_pa = sc->irq_sp->next_ba)) & ASC_RQ_DONE) != 0) |
2029 | { |
2030 | #if ADW_DEBUG |
2031 | printf("irq 0x%x, 0x%x, 0x%x, 0x%x\n" , |
2032 | sc->irq_sp->carr_id, |
2033 | sc->irq_sp->carr_ba, |
2034 | sc->irq_sp->areq_ba, |
2035 | sc->irq_sp->next_ba); |
2036 | #endif |
2037 | /* |
2038 | * Get a pointer to the newly completed ADW_SCSI_REQ_Q |
2039 | * structure. |
2040 | * The RISC will have set 'areq_ba' to a virtual address. |
2041 | * |
2042 | * The firmware will have copied the ASC_SCSI_REQ_Q.ccb_ptr |
2043 | * field to the carrier ADV_CARR_T.areq_ba field. |
2044 | * The conversion below complements the conversion of |
2045 | * ASC_SCSI_REQ_Q.scsiq_ptr' in AdwExeScsiQueue(). |
2046 | */ |
2047 | ccb = adw_ccb_phys_kv(sc, sc->irq_sp->areq_ba); |
2048 | scsiq = &ccb->scsiq; |
2049 | scsiq->ccb_ptr = sc->irq_sp->areq_ba; |
2050 | |
2051 | /* |
2052 | * Request finished with good status and the queue was not |
2053 | * DMAed to host memory by the firmware. Set all status fields |
2054 | * to indicate good status. |
2055 | */ |
2056 | if ((le32toh(irq_next_pa) & ASC_RQ_GOOD) != 0) { |
2057 | scsiq->done_status = QD_NO_ERROR; |
2058 | scsiq->host_status = scsiq->scsi_status = 0; |
2059 | scsiq->data_cnt = 0L; |
2060 | } |
2061 | |
2062 | /* |
2063 | * Advance the stopper pointer to the next carrier |
2064 | * ignoring the lower four bits. Free the previous |
2065 | * stopper carrier. |
2066 | */ |
2067 | free_carrp = sc->irq_sp; |
2068 | sc->irq_sp = ADW_CARRIER_VADDR(sc, ASC_GET_CARRP(irq_next_pa)); |
2069 | |
2070 | free_carrp->next_ba = (sc->carr_freelist == NULL) ? 0 |
2071 | : sc->carr_freelist->carr_ba; |
2072 | sc->carr_freelist = free_carrp; |
2073 | sc->carr_pending_cnt--; |
2074 | |
2075 | /* |
2076 | * Clear request microcode control flag. |
2077 | */ |
2078 | scsiq->cntl = 0; |
2079 | |
2080 | /* |
2081 | * Check Condition handling |
2082 | */ |
2083 | /* |
2084 | * If the command that completed was a SCSI INQUIRY and |
2085 | * LUN 0 was sent the command, then process the INQUIRY |
2086 | * command information for the device. |
2087 | */ |
2088 | if (scsiq->done_status == QD_NO_ERROR && |
2089 | scsiq->cdb[0] == INQUIRY && |
2090 | scsiq->target_lun == 0) { |
2091 | AdwInquiryHandling(sc, scsiq); |
2092 | } |
2093 | |
2094 | /* |
2095 | * Notify the driver of the completed request by passing |
2096 | * the ADW_SCSI_REQ_Q pointer to its callback function. |
2097 | */ |
2098 | (*(ADW_ISR_CALLBACK)sc->isr_callback)(sc, scsiq); |
2099 | /* |
2100 | * Note: After the driver callback function is called, 'scsiq' |
2101 | * can no longer be referenced. |
2102 | * |
2103 | * Fall through and continue processing other completed |
2104 | * requests... |
2105 | */ |
2106 | } |
2107 | |
2108 | splx(s); |
2109 | |
2110 | return ADW_TRUE; |
2111 | } |
2112 | |
2113 | |
2114 | /* |
2115 | * Send an idle command to the chip and wait for completion. |
2116 | * |
2117 | * Command completion is polled for once per microsecond. |
2118 | * |
2119 | * The function can be called from anywhere including an interrupt handler. |
2120 | * But the function is not re-entrant, so it uses the splbio/splx() |
2121 | * functions to prevent reentrancy. |
2122 | * |
2123 | * Return Values: |
2124 | * ADW_TRUE - command completed successfully |
2125 | * ADW_FALSE - command failed |
2126 | * ADW_ERROR - command timed out |
2127 | */ |
2128 | int |
2129 | AdwSendIdleCmd(ADW_SOFTC *sc, u_int16_t idle_cmd, u_int32_t idle_cmd_parameter) |
2130 | { |
2131 | bus_space_tag_t iot = sc->sc_iot; |
2132 | bus_space_handle_t ioh = sc->sc_ioh; |
2133 | u_int16_t result; |
2134 | u_int32_t i, j, s; |
2135 | |
2136 | s = splbio(); |
2137 | |
2138 | /* |
2139 | * Clear the idle command status which is set by the microcode |
2140 | * to a non-zero value to indicate when the command is completed. |
2141 | */ |
2142 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_IDLE_CMD_STATUS, (u_int16_t) 0); |
2143 | |
2144 | /* |
2145 | * Write the idle command value after the idle command parameter |
2146 | * has been written to avoid a race condition. If the order is not |
2147 | * followed, the microcode may process the idle command before the |
2148 | * parameters have been written to LRAM. |
2149 | */ |
2150 | ADW_WRITE_DWORD_LRAM(iot, ioh, ADW_MC_IDLE_CMD_PARAMETER, |
2151 | idle_cmd_parameter); |
2152 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_IDLE_CMD, idle_cmd); |
2153 | |
2154 | /* |
2155 | * Tickle the RISC to tell it to process the idle command. |
2156 | */ |
2157 | ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_TICKLE, ADW_TICKLE_B); |
2158 | if (sc->chip_type == ADW_CHIP_ASC3550) { |
2159 | /* |
2160 | * Clear the tickle value. In the ASC-3550 the RISC flag |
2161 | * command 'clr_tickle_b' does not work unless the host |
2162 | * value is cleared. |
2163 | */ |
2164 | ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_TICKLE, ADW_TICKLE_NOP); |
2165 | } |
2166 | |
2167 | /* Wait for up to 100 millisecond for the idle command to timeout. */ |
2168 | for (i = 0; i < SCSI_WAIT_100_MSEC; i++) { |
2169 | /* Poll once each microsecond for command completion. */ |
2170 | for (j = 0; j < SCSI_US_PER_MSEC; j++) { |
2171 | ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_IDLE_CMD_STATUS, |
2172 | result); |
2173 | if (result != 0) { |
2174 | splx(s); |
2175 | return result; |
2176 | } |
2177 | AdwDelayMicroSecond(1); |
2178 | } |
2179 | } |
2180 | |
2181 | splx(s); |
2182 | return ADW_ERROR; |
2183 | } |
2184 | |
2185 | |
2186 | /* |
2187 | * Inquiry Information Byte 7 Handling |
2188 | * |
2189 | * Handle SCSI Inquiry Command information for a device by setting |
2190 | * microcode operating variables that affect WDTR, SDTR, and Tag |
2191 | * Queuing. |
2192 | */ |
2193 | static void |
2194 | AdwInquiryHandling(ADW_SOFTC *sc, ADW_SCSI_REQ_Q *scsiq) |
2195 | { |
2196 | #ifndef FAILSAFE |
2197 | bus_space_tag_t iot = sc->sc_iot; |
2198 | bus_space_handle_t ioh = sc->sc_ioh; |
2199 | u_int8_t tid; |
2200 | struct scsipi_inquiry_data *inq; |
2201 | u_int16_t tidmask; |
2202 | u_int16_t cfg_word; |
2203 | |
2204 | |
2205 | /* |
2206 | * AdwInquiryHandling() requires up to INQUIRY information Byte 7 |
2207 | * to be available. |
2208 | * |
2209 | * If less than 8 bytes of INQUIRY information were requested or less |
2210 | * than 8 bytes were transferred, then return. cdb[4] is the request |
2211 | * length and the ADW_SCSI_REQ_Q 'data_cnt' field is set by the |
2212 | * microcode to the transfer residual count. |
2213 | */ |
2214 | |
2215 | if (scsiq->cdb[4] < 8 || (scsiq->cdb[4] - scsiq->data_cnt) < 8) { |
2216 | return; |
2217 | } |
2218 | |
2219 | tid = scsiq->target_id; |
2220 | |
2221 | inq = (struct scsipi_inquiry_data *) scsiq->vdata_addr; |
2222 | |
2223 | /* |
2224 | * WDTR, SDTR, and Tag Queuing cannot be enabled for old devices. |
2225 | */ |
2226 | if (((inq->response_format & SID_RespDataFmt) < 2) /*SCSI-1 | CCS*/ && |
2227 | ((inq->version & SID_ANSII) < 2)) { |
2228 | return; |
2229 | } else { |
2230 | /* |
2231 | * INQUIRY Byte 7 Handling |
2232 | * |
2233 | * Use a device's INQUIRY byte 7 to determine whether it |
2234 | * supports WDTR, SDTR, and Tag Queuing. If the feature |
2235 | * is enabled in the EEPROM and the device supports the |
2236 | * feature, then enable it in the microcode. |
2237 | */ |
2238 | |
2239 | tidmask = ADW_TID_TO_TIDMASK(tid); |
2240 | |
2241 | /* |
2242 | * Wide Transfers |
2243 | * |
2244 | * If the EEPROM enabled WDTR for the device and the device |
2245 | * supports wide bus (16 bit) transfers, then turn on the |
2246 | * device's 'wdtr_able' bit and write the new value to the |
2247 | * microcode. |
2248 | */ |
2249 | #ifdef SCSI_ADW_WDTR_DISABLE |
2250 | if(!(tidmask & SCSI_ADW_WDTR_DISABLE)) |
2251 | #endif /* SCSI_ADW_WDTR_DISABLE */ |
2252 | if ((sc->wdtr_able & tidmask) && (inq->flags3 & SID_WBus16)) { |
2253 | ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_WDTR_ABLE, |
2254 | cfg_word); |
2255 | if ((cfg_word & tidmask) == 0) { |
2256 | cfg_word |= tidmask; |
2257 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_WDTR_ABLE, |
2258 | cfg_word); |
2259 | |
2260 | /* |
2261 | * Clear the microcode "SDTR negotiation" and |
2262 | * "WDTR negotiation" done indicators for the |
2263 | * target to cause it to negotiate with the new |
2264 | * setting set above. |
2265 | * WDTR when accepted causes the target to enter |
2266 | * asynchronous mode, so SDTR must be negotiated |
2267 | */ |
2268 | ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_SDTR_DONE, |
2269 | cfg_word); |
2270 | cfg_word &= ~tidmask; |
2271 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_SDTR_DONE, |
2272 | cfg_word); |
2273 | ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_WDTR_DONE, |
2274 | cfg_word); |
2275 | cfg_word &= ~tidmask; |
2276 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_WDTR_DONE, |
2277 | cfg_word); |
2278 | } |
2279 | } |
2280 | |
2281 | /* |
2282 | * Synchronous Transfers |
2283 | * |
2284 | * If the EEPROM enabled SDTR for the device and the device |
2285 | * supports synchronous transfers, then turn on the device's |
2286 | * 'sdtr_able' bit. Write the new value to the microcode. |
2287 | */ |
2288 | #ifdef SCSI_ADW_SDTR_DISABLE |
2289 | if(!(tidmask & SCSI_ADW_SDTR_DISABLE)) |
2290 | #endif /* SCSI_ADW_SDTR_DISABLE */ |
2291 | if ((sc->sdtr_able & tidmask) && (inq->flags3 & SID_Sync)) { |
2292 | ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_SDTR_ABLE,cfg_word); |
2293 | if ((cfg_word & tidmask) == 0) { |
2294 | cfg_word |= tidmask; |
2295 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_SDTR_ABLE, |
2296 | cfg_word); |
2297 | |
2298 | /* |
2299 | * Clear the microcode "SDTR negotiation" |
2300 | * done indicator for the target to cause it |
2301 | * to negotiate with the new setting set above. |
2302 | */ |
2303 | ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_SDTR_DONE, |
2304 | cfg_word); |
2305 | cfg_word &= ~tidmask; |
2306 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_SDTR_DONE, |
2307 | cfg_word); |
2308 | } |
2309 | } |
2310 | /* |
2311 | * If the Inquiry data included enough space for the SPI-3 |
2312 | * Clocking field, then check if DT mode is supported. |
2313 | */ |
2314 | if (sc->chip_type == ADW_CHIP_ASC38C1600 && |
2315 | (scsiq->cdb[4] >= 57 || |
2316 | (scsiq->cdb[4] - scsiq->data_cnt) >= 57)) { |
2317 | /* |
2318 | * PPR (Parallel Protocol Request) Capable |
2319 | * |
2320 | * If the device supports DT mode, then it must be |
2321 | * PPR capable. |
2322 | * The PPR message will be used in place of the SDTR |
2323 | * and WDTR messages to negotiate synchronous speed |
2324 | * and offset, transfer width, and protocol options. |
2325 | */ |
2326 | if((inq->flags4 & SID_Clocking) & SID_CLOCKING_DT_ONLY){ |
2327 | ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_PPR_ABLE, |
2328 | sc->ppr_able); |
2329 | sc->ppr_able |= tidmask; |
2330 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_PPR_ABLE, |
2331 | sc->ppr_able); |
2332 | } |
2333 | } |
2334 | |
2335 | /* |
2336 | * If the EEPROM enabled Tag Queuing for the device and the |
2337 | * device supports Tag Queueing, then turn on the device's |
2338 | * 'tagqng_enable' bit in the microcode and set the microcode |
2339 | * maximum command count to the ADV_DVC_VAR 'max_dvc_qng' |
2340 | * value. |
2341 | * |
2342 | * Tag Queuing is disabled for the BIOS which runs in polled |
2343 | * mode and would see no benefit from Tag Queuing. Also by |
2344 | * disabling Tag Queuing in the BIOS devices with Tag Queuing |
2345 | * bugs will at least work with the BIOS. |
2346 | */ |
2347 | #ifdef SCSI_ADW_TAGQ_DISABLE |
2348 | if(!(tidmask & SCSI_ADW_TAGQ_DISABLE)) |
2349 | #endif /* SCSI_ADW_TAGQ_DISABLE */ |
2350 | if ((sc->tagqng_able & tidmask) && (inq->flags3 & SID_CmdQue)) { |
2351 | ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_TAGQNG_ABLE, |
2352 | cfg_word); |
2353 | cfg_word |= tidmask; |
2354 | ADW_WRITE_WORD_LRAM(iot, ioh, ADW_MC_TAGQNG_ABLE, |
2355 | cfg_word); |
2356 | |
2357 | ADW_WRITE_BYTE_LRAM(iot, ioh, |
2358 | ADW_MC_NUMBER_OF_MAX_CMD + tid, |
2359 | sc->max_dvc_qng); |
2360 | } |
2361 | } |
2362 | #endif /* FAILSAFE */ |
2363 | } |
2364 | |
2365 | |
2366 | static void |
2367 | AdwSleepMilliSecond(u_int32_t n) |
2368 | { |
2369 | |
2370 | DELAY(n * 1000); |
2371 | } |
2372 | |
2373 | |
2374 | static void |
2375 | AdwDelayMicroSecond(u_int32_t n) |
2376 | { |
2377 | |
2378 | DELAY(n); |
2379 | } |
2380 | |
2381 | |