1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include <linux/module.h>
19#include <linux/string.h>
20#include <linux/kernel.h>
21#include <linux/types.h>
22#include <linux/ioport.h>
23#include <linux/interrupt.h>
24#include <linux/delay.h>
25#include <linux/slab.h>
26#include <linux/mm.h>
27#include <linux/proc_fs.h>
28#include <linux/init.h>
29#include <linux/blkdev.h>
30#include <linux/isa.h>
31#include <linux/eisa.h>
32#include <linux/pci.h>
33#include <linux/spinlock.h>
34#include <linux/dma-mapping.h>
35#include <linux/firmware.h>
36#include <linux/dmapool.h>
37
38#include <asm/io.h>
39#include <asm/dma.h>
40
41#include <scsi/scsi_cmnd.h>
42#include <scsi/scsi_device.h>
43#include <scsi/scsi_tcq.h>
44#include <scsi/scsi.h>
45#include <scsi/scsi_host.h>
46
47#define DRV_NAME "advansys"
48#define ASC_VERSION "3.5"
49
50
51
52
53
54
55
56
57
58#define ADVANSYS_STATS
59
60
61#undef ADVANSYS_DEBUG
62
63typedef unsigned char uchar;
64
65#define isodd_word(val) ((((uint)val) & (uint)0x0001) != 0)
66
67#define PCI_VENDOR_ID_ASP 0x10cd
68#define PCI_DEVICE_ID_ASP_1200A 0x1100
69#define PCI_DEVICE_ID_ASP_ABP940 0x1200
70#define PCI_DEVICE_ID_ASP_ABP940U 0x1300
71#define PCI_DEVICE_ID_ASP_ABP940UW 0x2300
72#define PCI_DEVICE_ID_38C0800_REV1 0x2500
73#define PCI_DEVICE_ID_38C1600_REV1 0x2700
74
75#define PortAddr unsigned int
76#define inp(port) inb(port)
77#define outp(port, byte) outb((byte), (port))
78
79#define inpw(port) inw(port)
80#define outpw(port, word) outw((word), (port))
81
82#define ASC_MAX_SG_QUEUE 7
83#define ASC_MAX_SG_LIST 255
84
85#define ASC_CS_TYPE unsigned short
86
87#define ASC_IS_EISA (0x0002)
88#define ASC_IS_PCI (0x0004)
89#define ASC_IS_PCI_ULTRA (0x0104)
90#define ASC_IS_PCMCIA (0x0008)
91#define ASC_IS_MCA (0x0020)
92#define ASC_IS_VL (0x0040)
93#define ASC_IS_WIDESCSI_16 (0x0100)
94#define ASC_IS_WIDESCSI_32 (0x0200)
95#define ASC_IS_BIG_ENDIAN (0x8000)
96
97#define ASC_CHIP_MIN_VER_VL (0x01)
98#define ASC_CHIP_MAX_VER_VL (0x07)
99#define ASC_CHIP_MIN_VER_PCI (0x09)
100#define ASC_CHIP_MAX_VER_PCI (0x0F)
101#define ASC_CHIP_VER_PCI_BIT (0x08)
102#define ASC_CHIP_VER_ASYN_BUG (0x21)
103#define ASC_CHIP_VER_PCI 0x08
104#define ASC_CHIP_VER_PCI_ULTRA_3150 (ASC_CHIP_VER_PCI | 0x02)
105#define ASC_CHIP_VER_PCI_ULTRA_3050 (ASC_CHIP_VER_PCI | 0x03)
106#define ASC_CHIP_MIN_VER_EISA (0x41)
107#define ASC_CHIP_MAX_VER_EISA (0x47)
108#define ASC_CHIP_VER_EISA_BIT (0x40)
109#define ASC_CHIP_LATEST_VER_EISA ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
110#define ASC_MAX_VL_DMA_COUNT (0x07FFFFFFL)
111#define ASC_MAX_PCI_DMA_COUNT (0xFFFFFFFFL)
112
113#define ASC_SCSI_ID_BITS 3
114#define ASC_SCSI_TIX_TYPE uchar
115#define ASC_ALL_DEVICE_BIT_SET 0xFF
116#define ASC_SCSI_BIT_ID_TYPE uchar
117#define ASC_MAX_TID 7
118#define ASC_MAX_LUN 7
119#define ASC_SCSI_WIDTH_BIT_SET 0xFF
120#define ASC_MAX_SENSE_LEN 32
121#define ASC_MIN_SENSE_LEN 14
122#define ASC_SCSI_RESET_HOLD_TIME_US 60
123
124
125
126
127
128#define ASC_MAX_CDB_LEN 12
129#define ADV_MAX_CDB_LEN 16
130
131#define MS_SDTR_LEN 0x03
132#define MS_WDTR_LEN 0x02
133
134#define ASC_SG_LIST_PER_Q 7
135#define QS_FREE 0x00
136#define QS_READY 0x01
137#define QS_DISC1 0x02
138#define QS_DISC2 0x04
139#define QS_BUSY 0x08
140#define QS_ABORTED 0x40
141#define QS_DONE 0x80
142#define QC_NO_CALLBACK 0x01
143#define QC_SG_SWAP_QUEUE 0x02
144#define QC_SG_HEAD 0x04
145#define QC_DATA_IN 0x08
146#define QC_DATA_OUT 0x10
147#define QC_URGENT 0x20
148#define QC_MSG_OUT 0x40
149#define QC_REQ_SENSE 0x80
150#define QCSG_SG_XFER_LIST 0x02
151#define QCSG_SG_XFER_MORE 0x04
152#define QCSG_SG_XFER_END 0x08
153#define QD_IN_PROGRESS 0x00
154#define QD_NO_ERROR 0x01
155#define QD_ABORTED_BY_HOST 0x02
156#define QD_WITH_ERROR 0x04
157#define QD_INVALID_REQUEST 0x80
158#define QD_INVALID_HOST_NUM 0x81
159#define QD_INVALID_DEVICE 0x82
160#define QD_ERR_INTERNAL 0xFF
161#define QHSTA_NO_ERROR 0x00
162#define QHSTA_M_SEL_TIMEOUT 0x11
163#define QHSTA_M_DATA_OVER_RUN 0x12
164#define QHSTA_M_DATA_UNDER_RUN 0x12
165#define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
166#define QHSTA_M_BAD_BUS_PHASE_SEQ 0x14
167#define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
168#define QHSTA_D_ASC_DVC_ERROR_CODE_SET 0x22
169#define QHSTA_D_HOST_ABORT_FAILED 0x23
170#define QHSTA_D_EXE_SCSI_Q_FAILED 0x24
171#define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
172#define QHSTA_D_ASPI_NO_BUF_POOL 0x26
173#define QHSTA_M_WTM_TIMEOUT 0x41
174#define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
175#define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
176#define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
177#define QHSTA_M_TARGET_STATUS_BUSY 0x45
178#define QHSTA_M_BAD_TAG_CODE 0x46
179#define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY 0x47
180#define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
181#define QHSTA_D_LRAM_CMP_ERROR 0x81
182#define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
183#define ASC_FLAG_SCSIQ_REQ 0x01
184#define ASC_FLAG_BIOS_SCSIQ_REQ 0x02
185#define ASC_FLAG_BIOS_ASYNC_IO 0x04
186#define ASC_FLAG_SRB_LINEAR_ADDR 0x08
187#define ASC_FLAG_WIN16 0x10
188#define ASC_FLAG_WIN32 0x20
189#define ASC_FLAG_DOS_VM_CALLBACK 0x80
190#define ASC_TAG_FLAG_EXTRA_BYTES 0x10
191#define ASC_TAG_FLAG_DISABLE_DISCONNECT 0x04
192#define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX 0x08
193#define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
194#define ASC_SCSIQ_CPY_BEG 4
195#define ASC_SCSIQ_SGHD_CPY_BEG 2
196#define ASC_SCSIQ_B_FWD 0
197#define ASC_SCSIQ_B_BWD 1
198#define ASC_SCSIQ_B_STATUS 2
199#define ASC_SCSIQ_B_QNO 3
200#define ASC_SCSIQ_B_CNTL 4
201#define ASC_SCSIQ_B_SG_QUEUE_CNT 5
202#define ASC_SCSIQ_D_DATA_ADDR 8
203#define ASC_SCSIQ_D_DATA_CNT 12
204#define ASC_SCSIQ_B_SENSE_LEN 20
205#define ASC_SCSIQ_DONE_INFO_BEG 22
206#define ASC_SCSIQ_D_SRBPTR 22
207#define ASC_SCSIQ_B_TARGET_IX 26
208#define ASC_SCSIQ_B_CDB_LEN 28
209#define ASC_SCSIQ_B_TAG_CODE 29
210#define ASC_SCSIQ_W_VM_ID 30
211#define ASC_SCSIQ_DONE_STATUS 32
212#define ASC_SCSIQ_HOST_STATUS 33
213#define ASC_SCSIQ_SCSI_STATUS 34
214#define ASC_SCSIQ_CDB_BEG 36
215#define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
216#define ASC_SCSIQ_DW_REMAIN_XFER_CNT 60
217#define ASC_SCSIQ_B_FIRST_SG_WK_QP 48
218#define ASC_SCSIQ_B_SG_WK_QP 49
219#define ASC_SCSIQ_B_SG_WK_IX 50
220#define ASC_SCSIQ_W_ALT_DC1 52
221#define ASC_SCSIQ_B_LIST_CNT 6
222#define ASC_SCSIQ_B_CUR_LIST_CNT 7
223#define ASC_SGQ_B_SG_CNTL 4
224#define ASC_SGQ_B_SG_HEAD_QP 5
225#define ASC_SGQ_B_SG_LIST_CNT 6
226#define ASC_SGQ_B_SG_CUR_LIST_CNT 7
227#define ASC_SGQ_LIST_BEG 8
228#define ASC_DEF_SCSI1_QNG 4
229#define ASC_MAX_SCSI1_QNG 4
230#define ASC_DEF_SCSI2_QNG 16
231#define ASC_MAX_SCSI2_QNG 32
232#define ASC_TAG_CODE_MASK 0x23
233#define ASC_STOP_REQ_RISC_STOP 0x01
234#define ASC_STOP_ACK_RISC_STOP 0x03
235#define ASC_STOP_CLEAN_UP_BUSY_Q 0x10
236#define ASC_STOP_CLEAN_UP_DISC_Q 0x20
237#define ASC_STOP_HOST_REQ_RISC_HALT 0x40
238#define ASC_TIDLUN_TO_IX(tid, lun) (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
239#define ASC_TID_TO_TARGET_ID(tid) (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
240#define ASC_TIX_TO_TARGET_ID(tix) (0x01 << ((tix) & ASC_MAX_TID))
241#define ASC_TIX_TO_TID(tix) ((tix) & ASC_MAX_TID)
242#define ASC_TID_TO_TIX(tid) ((tid) & ASC_MAX_TID)
243#define ASC_TIX_TO_LUN(tix) (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
244#define ASC_QNO_TO_QADDR(q_no) ((ASC_QADR_BEG)+((int)(q_no) << 6))
245
246typedef struct asc_scsiq_1 {
247 uchar status;
248 uchar q_no;
249 uchar cntl;
250 uchar sg_queue_cnt;
251 uchar target_id;
252 uchar target_lun;
253 __le32 data_addr;
254 __le32 data_cnt;
255 __le32 sense_addr;
256 uchar sense_len;
257 uchar extra_bytes;
258} ASC_SCSIQ_1;
259
260typedef struct asc_scsiq_2 {
261 u32 srb_tag;
262 uchar target_ix;
263 uchar flag;
264 uchar cdb_len;
265 uchar tag_code;
266 ushort vm_id;
267} ASC_SCSIQ_2;
268
269typedef struct asc_scsiq_3 {
270 uchar done_stat;
271 uchar host_stat;
272 uchar scsi_stat;
273 uchar scsi_msg;
274} ASC_SCSIQ_3;
275
276typedef struct asc_scsiq_4 {
277 uchar cdb[ASC_MAX_CDB_LEN];
278 uchar y_first_sg_list_qp;
279 uchar y_working_sg_qp;
280 uchar y_working_sg_ix;
281 uchar y_res;
282 ushort x_req_count;
283 ushort x_reconnect_rtn;
284 __le32 x_saved_data_addr;
285 __le32 x_saved_data_cnt;
286} ASC_SCSIQ_4;
287
288typedef struct asc_q_done_info {
289 ASC_SCSIQ_2 d2;
290 ASC_SCSIQ_3 d3;
291 uchar q_status;
292 uchar q_no;
293 uchar cntl;
294 uchar sense_len;
295 uchar extra_bytes;
296 uchar res;
297 u32 remain_bytes;
298} ASC_QDONE_INFO;
299
300typedef struct asc_sg_list {
301 __le32 addr;
302 __le32 bytes;
303} ASC_SG_LIST;
304
305typedef struct asc_sg_head {
306 ushort entry_cnt;
307 ushort queue_cnt;
308 ushort entry_to_copy;
309 ushort res;
310 ASC_SG_LIST sg_list[];
311} ASC_SG_HEAD;
312
313typedef struct asc_scsi_q {
314 ASC_SCSIQ_1 q1;
315 ASC_SCSIQ_2 q2;
316 uchar *cdbptr;
317 ASC_SG_HEAD *sg_head;
318 ushort remain_sg_entry_cnt;
319 ushort next_sg_index;
320} ASC_SCSI_Q;
321
322typedef struct asc_scsi_bios_req_q {
323 ASC_SCSIQ_1 r1;
324 ASC_SCSIQ_2 r2;
325 uchar *cdbptr;
326 ASC_SG_HEAD *sg_head;
327 uchar *sense_ptr;
328 ASC_SCSIQ_3 r3;
329 uchar cdb[ASC_MAX_CDB_LEN];
330 uchar sense[ASC_MIN_SENSE_LEN];
331} ASC_SCSI_BIOS_REQ_Q;
332
333typedef struct asc_risc_q {
334 uchar fwd;
335 uchar bwd;
336 ASC_SCSIQ_1 i1;
337 ASC_SCSIQ_2 i2;
338 ASC_SCSIQ_3 i3;
339 ASC_SCSIQ_4 i4;
340} ASC_RISC_Q;
341
342typedef struct asc_sg_list_q {
343 uchar seq_no;
344 uchar q_no;
345 uchar cntl;
346 uchar sg_head_qp;
347 uchar sg_list_cnt;
348 uchar sg_cur_list_cnt;
349} ASC_SG_LIST_Q;
350
351typedef struct asc_risc_sg_list_q {
352 uchar fwd;
353 uchar bwd;
354 ASC_SG_LIST_Q sg;
355 ASC_SG_LIST sg_list[7];
356} ASC_RISC_SG_LIST_Q;
357
358#define ASCQ_ERR_Q_STATUS 0x0D
359#define ASCQ_ERR_CUR_QNG 0x17
360#define ASCQ_ERR_SG_Q_LINKS 0x18
361#define ASCQ_ERR_ISR_RE_ENTRY 0x1A
362#define ASCQ_ERR_CRITICAL_RE_ENTRY 0x1B
363#define ASCQ_ERR_ISR_ON_CRITICAL 0x1C
364
365
366
367
368#define ASC_WARN_NO_ERROR 0x0000
369#define ASC_WARN_IO_PORT_ROTATE 0x0001
370#define ASC_WARN_EEPROM_CHKSUM 0x0002
371#define ASC_WARN_IRQ_MODIFIED 0x0004
372#define ASC_WARN_AUTO_CONFIG 0x0008
373#define ASC_WARN_CMD_QNG_CONFLICT 0x0010
374#define ASC_WARN_EEPROM_RECOVER 0x0020
375#define ASC_WARN_CFG_MSW_RECOVER 0x0040
376
377
378
379
380#define ASC_IERR_NO_CARRIER 0x0001
381#define ASC_IERR_MCODE_CHKSUM 0x0002
382#define ASC_IERR_SET_PC_ADDR 0x0004
383#define ASC_IERR_START_STOP_CHIP 0x0008
384#define ASC_IERR_ILLEGAL_CONNECTION 0x0010
385#define ASC_IERR_SINGLE_END_DEVICE 0x0020
386#define ASC_IERR_REVERSED_CABLE 0x0040
387#define ASC_IERR_SET_SCSI_ID 0x0080
388#define ASC_IERR_HVD_DEVICE 0x0100
389#define ASC_IERR_BAD_SIGNATURE 0x0200
390#define ASC_IERR_NO_BUS_TYPE 0x0400
391#define ASC_IERR_BIST_PRE_TEST 0x0800
392#define ASC_IERR_BIST_RAM_TEST 0x1000
393#define ASC_IERR_BAD_CHIPTYPE 0x2000
394
395#define ASC_DEF_MAX_TOTAL_QNG (0xF0)
396#define ASC_MIN_TAG_Q_PER_DVC (0x04)
397#define ASC_MIN_FREE_Q (0x02)
398#define ASC_MIN_TOTAL_QNG ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
399#define ASC_MAX_TOTAL_QNG 240
400#define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
401#define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG 8
402#define ASC_MAX_PCI_INRAM_TOTAL_QNG 20
403#define ASC_MAX_INRAM_TAG_QNG 16
404#define ASC_IOADR_GAP 0x10
405#define ASC_SYN_MAX_OFFSET 0x0F
406#define ASC_DEF_SDTR_OFFSET 0x0F
407#define ASC_SDTR_ULTRA_PCI_10MB_INDEX 0x02
408#define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
409
410
411
412
413
414static const unsigned char asc_syn_xfer_period[8] = {
415 25, 30, 35, 40, 50, 60, 70, 85
416};
417
418static const unsigned char asc_syn_ultra_xfer_period[16] = {
419 12, 19, 25, 32, 38, 44, 50, 57, 63, 69, 75, 82, 88, 94, 100, 107
420};
421
422typedef struct ext_msg {
423 uchar msg_type;
424 uchar msg_len;
425 uchar msg_req;
426 union {
427 struct {
428 uchar sdtr_xfer_period;
429 uchar sdtr_req_ack_offset;
430 } sdtr;
431 struct {
432 uchar wdtr_width;
433 } wdtr;
434 struct {
435 uchar mdp_b3;
436 uchar mdp_b2;
437 uchar mdp_b1;
438 uchar mdp_b0;
439 } mdp;
440 } u_ext_msg;
441 uchar res;
442} EXT_MSG;
443
444#define xfer_period u_ext_msg.sdtr.sdtr_xfer_period
445#define req_ack_offset u_ext_msg.sdtr.sdtr_req_ack_offset
446#define wdtr_width u_ext_msg.wdtr.wdtr_width
447#define mdp_b3 u_ext_msg.mdp_b3
448#define mdp_b2 u_ext_msg.mdp_b2
449#define mdp_b1 u_ext_msg.mdp_b1
450#define mdp_b0 u_ext_msg.mdp_b0
451
452typedef struct asc_dvc_cfg {
453 ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
454 ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
455 ASC_SCSI_BIT_ID_TYPE disc_enable;
456 ASC_SCSI_BIT_ID_TYPE sdtr_enable;
457 uchar chip_scsi_id;
458 uchar chip_version;
459 ushort mcode_date;
460 ushort mcode_version;
461 uchar max_tag_qng[ASC_MAX_TID + 1];
462 uchar sdtr_period_offset[ASC_MAX_TID + 1];
463 uchar adapter_info[6];
464} ASC_DVC_CFG;
465
466#define ASC_DEF_DVC_CNTL 0xFFFF
467#define ASC_DEF_CHIP_SCSI_ID 7
468#define ASC_DEF_ISA_DMA_SPEED 4
469#define ASC_INIT_STATE_BEG_GET_CFG 0x0001
470#define ASC_INIT_STATE_END_GET_CFG 0x0002
471#define ASC_INIT_STATE_BEG_SET_CFG 0x0004
472#define ASC_INIT_STATE_END_SET_CFG 0x0008
473#define ASC_INIT_STATE_BEG_LOAD_MC 0x0010
474#define ASC_INIT_STATE_END_LOAD_MC 0x0020
475#define ASC_INIT_STATE_BEG_INQUIRY 0x0040
476#define ASC_INIT_STATE_END_INQUIRY 0x0080
477#define ASC_INIT_RESET_SCSI_DONE 0x0100
478#define ASC_INIT_STATE_WITHOUT_EEP 0x8000
479#define ASC_BUG_FIX_IF_NOT_DWB 0x0001
480#define ASC_BUG_FIX_ASYN_USE_SYN 0x0002
481#define ASC_MIN_TAGGED_CMD 7
482#define ASC_MAX_SCSI_RESET_WAIT 30
483#define ASC_OVERRUN_BSIZE 64
484
485struct asc_dvc_var;
486
487typedef struct asc_dvc_var {
488 PortAddr iop_base;
489 ushort err_code;
490 ushort dvc_cntl;
491 ushort bug_fix_cntl;
492 ushort bus_type;
493 ASC_SCSI_BIT_ID_TYPE init_sdtr;
494 ASC_SCSI_BIT_ID_TYPE sdtr_done;
495 ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
496 ASC_SCSI_BIT_ID_TYPE unit_not_ready;
497 ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
498 ASC_SCSI_BIT_ID_TYPE start_motor;
499 uchar *overrun_buf;
500 dma_addr_t overrun_dma;
501 uchar scsi_reset_wait;
502 uchar chip_no;
503 bool is_in_int;
504 uchar max_total_qng;
505 uchar cur_total_qng;
506 uchar in_critical_cnt;
507 uchar last_q_shortage;
508 ushort init_state;
509 uchar cur_dvc_qng[ASC_MAX_TID + 1];
510 uchar max_dvc_qng[ASC_MAX_TID + 1];
511 ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1];
512 ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1];
513 const uchar *sdtr_period_tbl;
514 ASC_DVC_CFG *cfg;
515 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
516 char redo_scam;
517 ushort res2;
518 uchar dos_int13_table[ASC_MAX_TID + 1];
519 unsigned int max_dma_count;
520 ASC_SCSI_BIT_ID_TYPE no_scam;
521 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
522 uchar min_sdtr_index;
523 uchar max_sdtr_index;
524 struct asc_board *drv_ptr;
525 unsigned int uc_break;
526} ASC_DVC_VAR;
527
528typedef struct asc_dvc_inq_info {
529 uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
530} ASC_DVC_INQ_INFO;
531
532typedef struct asc_cap_info {
533 u32 lba;
534 u32 blk_size;
535} ASC_CAP_INFO;
536
537typedef struct asc_cap_info_array {
538 ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
539} ASC_CAP_INFO_ARRAY;
540
541#define ASC_MCNTL_NO_SEL_TIMEOUT (ushort)0x0001
542#define ASC_MCNTL_NULL_TARGET (ushort)0x0002
543#define ASC_CNTL_INITIATOR (ushort)0x0001
544#define ASC_CNTL_BIOS_GT_1GB (ushort)0x0002
545#define ASC_CNTL_BIOS_GT_2_DISK (ushort)0x0004
546#define ASC_CNTL_BIOS_REMOVABLE (ushort)0x0008
547#define ASC_CNTL_NO_SCAM (ushort)0x0010
548#define ASC_CNTL_INT_MULTI_Q (ushort)0x0080
549#define ASC_CNTL_NO_LUN_SUPPORT (ushort)0x0040
550#define ASC_CNTL_NO_VERIFY_COPY (ushort)0x0100
551#define ASC_CNTL_RESET_SCSI (ushort)0x0200
552#define ASC_CNTL_INIT_INQUIRY (ushort)0x0400
553#define ASC_CNTL_INIT_VERBOSE (ushort)0x0800
554#define ASC_CNTL_SCSI_PARITY (ushort)0x1000
555#define ASC_CNTL_BURST_MODE (ushort)0x2000
556#define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
557#define ASC_EEP_DVC_CFG_BEG_VL 2
558#define ASC_EEP_MAX_DVC_ADDR_VL 15
559#define ASC_EEP_DVC_CFG_BEG 32
560#define ASC_EEP_MAX_DVC_ADDR 45
561#define ASC_EEP_MAX_RETRY 20
562
563
564
565
566
567
568#define ASC_EEP_GET_CHIP_ID(cfg) ((cfg)->id_speed & 0x0f)
569#define ASC_EEP_GET_DMA_SPD(cfg) (((cfg)->id_speed & 0xf0) >> 4)
570#define ASC_EEP_SET_CHIP_ID(cfg, sid) \
571 ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))
572#define ASC_EEP_SET_DMA_SPD(cfg, spd) \
573 ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)
574
575typedef struct asceep_config {
576 ushort cfg_lsw;
577 ushort cfg_msw;
578 uchar init_sdtr;
579 uchar disc_enable;
580 uchar use_cmd_qng;
581 uchar start_motor;
582 uchar max_total_qng;
583 uchar max_tag_qng;
584 uchar bios_scan;
585 uchar power_up_wait;
586 uchar no_scam;
587 uchar id_speed;
588
589 uchar dos_int13_table[ASC_MAX_TID + 1];
590 uchar adapter_info[6];
591 ushort cntl;
592 ushort chksum;
593} ASCEEP_CONFIG;
594
595#define ASC_EEP_CMD_READ 0x80
596#define ASC_EEP_CMD_WRITE 0x40
597#define ASC_EEP_CMD_WRITE_ABLE 0x30
598#define ASC_EEP_CMD_WRITE_DISABLE 0x00
599#define ASCV_MSGOUT_BEG 0x0000
600#define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
601#define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
602#define ASCV_BREAK_SAVED_CODE (ushort)0x0006
603#define ASCV_MSGIN_BEG (ASCV_MSGOUT_BEG+8)
604#define ASCV_MSGIN_SDTR_PERIOD (ASCV_MSGIN_BEG+3)
605#define ASCV_MSGIN_SDTR_OFFSET (ASCV_MSGIN_BEG+4)
606#define ASCV_SDTR_DATA_BEG (ASCV_MSGIN_BEG+8)
607#define ASCV_SDTR_DONE_BEG (ASCV_SDTR_DATA_BEG+8)
608#define ASCV_MAX_DVC_QNG_BEG (ushort)0x0020
609#define ASCV_BREAK_ADDR (ushort)0x0028
610#define ASCV_BREAK_NOTIFY_COUNT (ushort)0x002A
611#define ASCV_BREAK_CONTROL (ushort)0x002C
612#define ASCV_BREAK_HIT_COUNT (ushort)0x002E
613
614#define ASCV_ASCDVC_ERR_CODE_W (ushort)0x0030
615#define ASCV_MCODE_CHKSUM_W (ushort)0x0032
616#define ASCV_MCODE_SIZE_W (ushort)0x0034
617#define ASCV_STOP_CODE_B (ushort)0x0036
618#define ASCV_DVC_ERR_CODE_B (ushort)0x0037
619#define ASCV_OVERRUN_PADDR_D (ushort)0x0038
620#define ASCV_OVERRUN_BSIZE_D (ushort)0x003C
621#define ASCV_HALTCODE_W (ushort)0x0040
622#define ASCV_CHKSUM_W (ushort)0x0042
623#define ASCV_MC_DATE_W (ushort)0x0044
624#define ASCV_MC_VER_W (ushort)0x0046
625#define ASCV_NEXTRDY_B (ushort)0x0048
626#define ASCV_DONENEXT_B (ushort)0x0049
627#define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
628#define ASCV_SCSIBUSY_B (ushort)0x004B
629#define ASCV_Q_DONE_IN_PROGRESS_B (ushort)0x004C
630#define ASCV_CURCDB_B (ushort)0x004D
631#define ASCV_RCLUN_B (ushort)0x004E
632#define ASCV_BUSY_QHEAD_B (ushort)0x004F
633#define ASCV_DISC1_QHEAD_B (ushort)0x0050
634#define ASCV_DISC_ENABLE_B (ushort)0x0052
635#define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
636#define ASCV_HOSTSCSI_ID_B (ushort)0x0055
637#define ASCV_MCODE_CNTL_B (ushort)0x0056
638#define ASCV_NULL_TARGET_B (ushort)0x0057
639#define ASCV_FREE_Q_HEAD_W (ushort)0x0058
640#define ASCV_DONE_Q_TAIL_W (ushort)0x005A
641#define ASCV_FREE_Q_HEAD_B (ushort)(ASCV_FREE_Q_HEAD_W+1)
642#define ASCV_DONE_Q_TAIL_B (ushort)(ASCV_DONE_Q_TAIL_W+1)
643#define ASCV_HOST_FLAG_B (ushort)0x005D
644#define ASCV_TOTAL_READY_Q_B (ushort)0x0064
645#define ASCV_VER_SERIAL_B (ushort)0x0065
646#define ASCV_HALTCODE_SAVED_W (ushort)0x0066
647#define ASCV_WTM_FLAG_B (ushort)0x0068
648#define ASCV_RISC_FLAG_B (ushort)0x006A
649#define ASCV_REQ_SG_LIST_QP (ushort)0x006B
650#define ASC_HOST_FLAG_IN_ISR 0x01
651#define ASC_HOST_FLAG_ACK_INT 0x02
652#define ASC_RISC_FLAG_GEN_INT 0x01
653#define ASC_RISC_FLAG_REQ_SG_LIST 0x02
654#define IOP_CTRL (0x0F)
655#define IOP_STATUS (0x0E)
656#define IOP_INT_ACK IOP_STATUS
657#define IOP_REG_IFC (0x0D)
658#define IOP_SYN_OFFSET (0x0B)
659#define IOP_EXTRA_CONTROL (0x0D)
660#define IOP_REG_PC (0x0C)
661#define IOP_RAM_ADDR (0x0A)
662#define IOP_RAM_DATA (0x08)
663#define IOP_EEP_DATA (0x06)
664#define IOP_EEP_CMD (0x07)
665#define IOP_VERSION (0x03)
666#define IOP_CONFIG_HIGH (0x04)
667#define IOP_CONFIG_LOW (0x02)
668#define IOP_SIG_BYTE (0x01)
669#define IOP_SIG_WORD (0x00)
670#define IOP_REG_DC1 (0x0E)
671#define IOP_REG_DC0 (0x0C)
672#define IOP_REG_SB (0x0B)
673#define IOP_REG_DA1 (0x0A)
674#define IOP_REG_DA0 (0x08)
675#define IOP_REG_SC (0x09)
676#define IOP_DMA_SPEED (0x07)
677#define IOP_REG_FLAG (0x07)
678#define IOP_FIFO_H (0x06)
679#define IOP_FIFO_L (0x04)
680#define IOP_REG_ID (0x05)
681#define IOP_REG_QP (0x03)
682#define IOP_REG_IH (0x02)
683#define IOP_REG_IX (0x01)
684#define IOP_REG_AX (0x00)
685#define IFC_REG_LOCK (0x00)
686#define IFC_REG_UNLOCK (0x09)
687#define IFC_WR_EN_FILTER (0x10)
688#define IFC_RD_NO_EEPROM (0x10)
689#define IFC_SLEW_RATE (0x20)
690#define IFC_ACT_NEG (0x40)
691#define IFC_INP_FILTER (0x80)
692#define IFC_INIT_DEFAULT (IFC_ACT_NEG | IFC_REG_UNLOCK)
693#define SC_SEL (uchar)(0x80)
694#define SC_BSY (uchar)(0x40)
695#define SC_ACK (uchar)(0x20)
696#define SC_REQ (uchar)(0x10)
697#define SC_ATN (uchar)(0x08)
698#define SC_IO (uchar)(0x04)
699#define SC_CD (uchar)(0x02)
700#define SC_MSG (uchar)(0x01)
701#define SEC_SCSI_CTL (uchar)(0x80)
702#define SEC_ACTIVE_NEGATE (uchar)(0x40)
703#define SEC_SLEW_RATE (uchar)(0x20)
704#define SEC_ENABLE_FILTER (uchar)(0x10)
705#define ASC_HALT_EXTMSG_IN (ushort)0x8000
706#define ASC_HALT_CHK_CONDITION (ushort)0x8100
707#define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
708#define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX (ushort)0x8300
709#define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX (ushort)0x8400
710#define ASC_HALT_SDTR_REJECTED (ushort)0x4000
711#define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
712#define ASC_MAX_QNO 0xF8
713#define ASC_DATA_SEC_BEG (ushort)0x0080
714#define ASC_DATA_SEC_END (ushort)0x0080
715#define ASC_CODE_SEC_BEG (ushort)0x0080
716#define ASC_CODE_SEC_END (ushort)0x0080
717#define ASC_QADR_BEG (0x4000)
718#define ASC_QADR_USED (ushort)(ASC_MAX_QNO * 64)
719#define ASC_QADR_END (ushort)0x7FFF
720#define ASC_QLAST_ADR (ushort)0x7FC0
721#define ASC_QBLK_SIZE 0x40
722#define ASC_BIOS_DATA_QBEG 0xF8
723#define ASC_MIN_ACTIVE_QNO 0x01
724#define ASC_QLINK_END 0xFF
725#define ASC_EEPROM_WORDS 0x10
726#define ASC_MAX_MGS_LEN 0x10
727#define ASC_BIOS_ADDR_DEF 0xDC00
728#define ASC_BIOS_SIZE 0x3800
729#define ASC_BIOS_RAM_OFF 0x3800
730#define ASC_BIOS_RAM_SIZE 0x800
731#define ASC_BIOS_MIN_ADDR 0xC000
732#define ASC_BIOS_MAX_ADDR 0xEC00
733#define ASC_BIOS_BANK_SIZE 0x0400
734#define ASC_MCODE_START_ADDR 0x0080
735#define ASC_CFG0_HOST_INT_ON 0x0020
736#define ASC_CFG0_BIOS_ON 0x0040
737#define ASC_CFG0_VERA_BURST_ON 0x0080
738#define ASC_CFG0_SCSI_PARITY_ON 0x0800
739#define ASC_CFG1_SCSI_TARGET_ON 0x0080
740#define ASC_CFG1_LRAM_8BITS_ON 0x0800
741#define ASC_CFG_MSW_CLR_MASK 0x3080
742#define CSW_TEST1 (ASC_CS_TYPE)0x8000
743#define CSW_AUTO_CONFIG (ASC_CS_TYPE)0x4000
744#define CSW_RESERVED1 (ASC_CS_TYPE)0x2000
745#define CSW_IRQ_WRITTEN (ASC_CS_TYPE)0x1000
746#define CSW_33MHZ_SELECTED (ASC_CS_TYPE)0x0800
747#define CSW_TEST2 (ASC_CS_TYPE)0x0400
748#define CSW_TEST3 (ASC_CS_TYPE)0x0200
749#define CSW_RESERVED2 (ASC_CS_TYPE)0x0100
750#define CSW_DMA_DONE (ASC_CS_TYPE)0x0080
751#define CSW_FIFO_RDY (ASC_CS_TYPE)0x0040
752#define CSW_EEP_READ_DONE (ASC_CS_TYPE)0x0020
753#define CSW_HALTED (ASC_CS_TYPE)0x0010
754#define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
755#define CSW_PARITY_ERR (ASC_CS_TYPE)0x0004
756#define CSW_SCSI_RESET_LATCH (ASC_CS_TYPE)0x0002
757#define CSW_INT_PENDING (ASC_CS_TYPE)0x0001
758#define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
759#define CIW_INT_ACK (ASC_CS_TYPE)0x0100
760#define CIW_TEST1 (ASC_CS_TYPE)0x0200
761#define CIW_TEST2 (ASC_CS_TYPE)0x0400
762#define CIW_SEL_33MHZ (ASC_CS_TYPE)0x0800
763#define CIW_IRQ_ACT (ASC_CS_TYPE)0x1000
764#define CC_CHIP_RESET (uchar)0x80
765#define CC_SCSI_RESET (uchar)0x40
766#define CC_HALT (uchar)0x20
767#define CC_SINGLE_STEP (uchar)0x10
768#define CC_DMA_ABLE (uchar)0x08
769#define CC_TEST (uchar)0x04
770#define CC_BANK_ONE (uchar)0x02
771#define CC_DIAG (uchar)0x01
772#define ASC_1000_ID0W 0x04C1
773#define ASC_1000_ID0W_FIX 0x00C1
774#define ASC_1000_ID1B 0x25
775#define ASC_EISA_REV_IOP_MASK (0x0C83)
776#define ASC_EISA_CFG_IOP_MASK (0x0C86)
777#define ASC_GET_EISA_SLOT(iop) (PortAddr)((iop) & 0xF000)
778#define INS_HALTINT (ushort)0x6281
779#define INS_HALT (ushort)0x6280
780#define INS_SINT (ushort)0x6200
781#define INS_RFLAG_WTM (ushort)0x7380
782#define ASC_MC_SAVE_CODE_WSIZE 0x500
783#define ASC_MC_SAVE_DATA_WSIZE 0x40
784
785typedef struct asc_mc_saved {
786 ushort data[ASC_MC_SAVE_DATA_WSIZE];
787 ushort code[ASC_MC_SAVE_CODE_WSIZE];
788} ASC_MC_SAVED;
789
790#define AscGetQDoneInProgress(port) AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
791#define AscPutQDoneInProgress(port, val) AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
792#define AscGetVarFreeQHead(port) AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
793#define AscGetVarDoneQTail(port) AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
794#define AscPutVarFreeQHead(port, val) AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
795#define AscPutVarDoneQTail(port, val) AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
796#define AscGetRiscVarFreeQHead(port) AscReadLramByte((port), ASCV_NEXTRDY_B)
797#define AscGetRiscVarDoneQTail(port) AscReadLramByte((port), ASCV_DONENEXT_B)
798#define AscPutRiscVarFreeQHead(port, val) AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
799#define AscPutRiscVarDoneQTail(port, val) AscWriteLramByte((port), ASCV_DONENEXT_B, val)
800#define AscPutMCodeSDTRDoneAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data))
801#define AscGetMCodeSDTRDoneAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id))
802#define AscPutMCodeInitSDTRAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data)
803#define AscGetMCodeInitSDTRAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id))
804#define AscGetChipSignatureByte(port) (uchar)inp((port)+IOP_SIG_BYTE)
805#define AscGetChipSignatureWord(port) (ushort)inpw((port)+IOP_SIG_WORD)
806#define AscGetChipVerNo(port) (uchar)inp((port)+IOP_VERSION)
807#define AscGetChipCfgLsw(port) (ushort)inpw((port)+IOP_CONFIG_LOW)
808#define AscGetChipCfgMsw(port) (ushort)inpw((port)+IOP_CONFIG_HIGH)
809#define AscSetChipCfgLsw(port, data) outpw((port)+IOP_CONFIG_LOW, data)
810#define AscSetChipCfgMsw(port, data) outpw((port)+IOP_CONFIG_HIGH, data)
811#define AscGetChipEEPCmd(port) (uchar)inp((port)+IOP_EEP_CMD)
812#define AscSetChipEEPCmd(port, data) outp((port)+IOP_EEP_CMD, data)
813#define AscGetChipEEPData(port) (ushort)inpw((port)+IOP_EEP_DATA)
814#define AscSetChipEEPData(port, data) outpw((port)+IOP_EEP_DATA, data)
815#define AscGetChipLramAddr(port) (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
816#define AscSetChipLramAddr(port, addr) outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
817#define AscGetChipLramData(port) (ushort)inpw((port)+IOP_RAM_DATA)
818#define AscSetChipLramData(port, data) outpw((port)+IOP_RAM_DATA, data)
819#define AscGetChipIFC(port) (uchar)inp((port)+IOP_REG_IFC)
820#define AscSetChipIFC(port, data) outp((port)+IOP_REG_IFC, data)
821#define AscGetChipStatus(port) (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
822#define AscSetChipStatus(port, cs_val) outpw((port)+IOP_STATUS, cs_val)
823#define AscGetChipControl(port) (uchar)inp((port)+IOP_CTRL)
824#define AscSetChipControl(port, cc_val) outp((port)+IOP_CTRL, cc_val)
825#define AscGetChipSyn(port) (uchar)inp((port)+IOP_SYN_OFFSET)
826#define AscSetChipSyn(port, data) outp((port)+IOP_SYN_OFFSET, data)
827#define AscSetPCAddr(port, data) outpw((port)+IOP_REG_PC, data)
828#define AscGetPCAddr(port) (ushort)inpw((port)+IOP_REG_PC)
829#define AscIsIntPending(port) (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
830#define AscGetChipScsiID(port) ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
831#define AscGetExtraControl(port) (uchar)inp((port)+IOP_EXTRA_CONTROL)
832#define AscSetExtraControl(port, data) outp((port)+IOP_EXTRA_CONTROL, data)
833#define AscReadChipAX(port) (ushort)inpw((port)+IOP_REG_AX)
834#define AscWriteChipAX(port, data) outpw((port)+IOP_REG_AX, data)
835#define AscReadChipIX(port) (uchar)inp((port)+IOP_REG_IX)
836#define AscWriteChipIX(port, data) outp((port)+IOP_REG_IX, data)
837#define AscReadChipIH(port) (ushort)inpw((port)+IOP_REG_IH)
838#define AscWriteChipIH(port, data) outpw((port)+IOP_REG_IH, data)
839#define AscReadChipQP(port) (uchar)inp((port)+IOP_REG_QP)
840#define AscWriteChipQP(port, data) outp((port)+IOP_REG_QP, data)
841#define AscReadChipFIFO_L(port) (ushort)inpw((port)+IOP_REG_FIFO_L)
842#define AscWriteChipFIFO_L(port, data) outpw((port)+IOP_REG_FIFO_L, data)
843#define AscReadChipFIFO_H(port) (ushort)inpw((port)+IOP_REG_FIFO_H)
844#define AscWriteChipFIFO_H(port, data) outpw((port)+IOP_REG_FIFO_H, data)
845#define AscReadChipDmaSpeed(port) (uchar)inp((port)+IOP_DMA_SPEED)
846#define AscWriteChipDmaSpeed(port, data) outp((port)+IOP_DMA_SPEED, data)
847#define AscReadChipDA0(port) (ushort)inpw((port)+IOP_REG_DA0)
848#define AscWriteChipDA0(port) outpw((port)+IOP_REG_DA0, data)
849#define AscReadChipDA1(port) (ushort)inpw((port)+IOP_REG_DA1)
850#define AscWriteChipDA1(port) outpw((port)+IOP_REG_DA1, data)
851#define AscReadChipDC0(port) (ushort)inpw((port)+IOP_REG_DC0)
852#define AscWriteChipDC0(port) outpw((port)+IOP_REG_DC0, data)
853#define AscReadChipDC1(port) (ushort)inpw((port)+IOP_REG_DC1)
854#define AscWriteChipDC1(port) outpw((port)+IOP_REG_DC1, data)
855#define AscReadChipDvcID(port) (uchar)inp((port)+IOP_REG_ID)
856#define AscWriteChipDvcID(port, data) outp((port)+IOP_REG_ID, data)
857
858#define AdvPortAddr void __iomem *
859
860
861
862
863#define ADV_MEM_READB(addr) readb(addr)
864#define ADV_MEM_READW(addr) readw(addr)
865#define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
866#define ADV_MEM_WRITEW(addr, word) writew(word, addr)
867#define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr)
868
869
870
871
872
873
874
875
876
877
878#define ADV_TOT_SG_BLOCK ASC_DEF_MAX_HOST_QNG
879
880
881
882
883#define ADV_MAX_SG_LIST 255
884#define NO_OF_SG_PER_BLOCK 15
885
886#define ADV_EEP_DVC_CFG_BEGIN (0x00)
887#define ADV_EEP_DVC_CFG_END (0x15)
888#define ADV_EEP_DVC_CTL_BEGIN (0x16)
889#define ADV_EEP_MAX_WORD_ADDR (0x1E)
890
891#define ADV_EEP_DELAY_MS 100
892
893#define ADV_EEPROM_BIG_ENDIAN 0x8000
894#define ADV_EEPROM_BIOS_ENABLE 0x4000
895
896
897
898
899
900#define ADV_EEPROM_TERM_POL 0x2000
901#define ADV_EEPROM_CIS_LD 0x2000
902
903
904
905
906
907
908
909
910
911
912
913#define ADV_EEPROM_INTAB 0x0800
914
915typedef struct adveep_3550_config {
916
917
918 ushort cfg_lsw;
919
920
921
922 ushort cfg_msw;
923 ushort disc_enable;
924 ushort wdtr_able;
925 ushort sdtr_able;
926 ushort start_motor;
927 ushort tagqng_able;
928 ushort bios_scan;
929 ushort scam_tolerant;
930
931 uchar adapter_scsi_id;
932 uchar bios_boot_delay;
933
934 uchar scsi_reset_delay;
935 uchar bios_id_lun;
936
937
938
939 uchar termination;
940
941
942
943
944
945 uchar reserved1;
946
947 ushort bios_ctrl;
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964 ushort ultra_able;
965 ushort reserved2;
966 uchar max_host_qng;
967 uchar max_dvc_qng;
968 ushort dvc_cntl;
969 ushort bug_fix;
970 ushort serial_number_word1;
971 ushort serial_number_word2;
972 ushort serial_number_word3;
973 ushort check_sum;
974 uchar oem_name[16];
975 ushort dvc_err_code;
976 ushort adv_err_code;
977 ushort adv_err_addr;
978 ushort saved_dvc_err_code;
979 ushort saved_adv_err_code;
980 ushort saved_adv_err_addr;
981 ushort num_of_err;
982} ADVEEP_3550_CONFIG;
983
984typedef struct adveep_38C0800_config {
985
986
987 ushort cfg_lsw;
988
989
990
991 ushort cfg_msw;
992 ushort disc_enable;
993 ushort wdtr_able;
994 ushort sdtr_speed1;
995 ushort start_motor;
996 ushort tagqng_able;
997 ushort bios_scan;
998 ushort scam_tolerant;
999
1000 uchar adapter_scsi_id;
1001 uchar bios_boot_delay;
1002
1003 uchar scsi_reset_delay;
1004 uchar bios_id_lun;
1005
1006
1007
1008 uchar termination_se;
1009
1010
1011
1012
1013
1014 uchar termination_lvd;
1015
1016
1017
1018
1019
1020 ushort bios_ctrl;
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037 ushort sdtr_speed2;
1038 ushort sdtr_speed3;
1039 uchar max_host_qng;
1040 uchar max_dvc_qng;
1041 ushort dvc_cntl;
1042 ushort sdtr_speed4;
1043 ushort serial_number_word1;
1044 ushort serial_number_word2;
1045 ushort serial_number_word3;
1046 ushort check_sum;
1047 uchar oem_name[16];
1048 ushort dvc_err_code;
1049 ushort adv_err_code;
1050 ushort adv_err_addr;
1051 ushort saved_dvc_err_code;
1052 ushort saved_adv_err_code;
1053 ushort saved_adv_err_addr;
1054 ushort reserved36;
1055 ushort reserved37;
1056 ushort reserved38;
1057 ushort reserved39;
1058 ushort reserved40;
1059 ushort reserved41;
1060 ushort reserved42;
1061 ushort reserved43;
1062 ushort reserved44;
1063 ushort reserved45;
1064 ushort reserved46;
1065 ushort reserved47;
1066 ushort reserved48;
1067 ushort reserved49;
1068 ushort reserved50;
1069 ushort reserved51;
1070 ushort reserved52;
1071 ushort reserved53;
1072 ushort reserved54;
1073 ushort reserved55;
1074 ushort cisptr_lsw;
1075 ushort cisprt_msw;
1076 ushort subsysvid;
1077 ushort subsysid;
1078 ushort reserved60;
1079 ushort reserved61;
1080 ushort reserved62;
1081 ushort reserved63;
1082} ADVEEP_38C0800_CONFIG;
1083
1084typedef struct adveep_38C1600_config {
1085
1086
1087 ushort cfg_lsw;
1088
1089
1090
1091
1092
1093 ushort cfg_msw;
1094 ushort disc_enable;
1095 ushort wdtr_able;
1096 ushort sdtr_speed1;
1097 ushort start_motor;
1098 ushort tagqng_able;
1099 ushort bios_scan;
1100 ushort scam_tolerant;
1101
1102 uchar adapter_scsi_id;
1103 uchar bios_boot_delay;
1104
1105 uchar scsi_reset_delay;
1106 uchar bios_id_lun;
1107
1108
1109
1110 uchar termination_se;
1111
1112
1113
1114
1115
1116 uchar termination_lvd;
1117
1118
1119
1120
1121
1122 ushort bios_ctrl;
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139 ushort sdtr_speed2;
1140 ushort sdtr_speed3;
1141 uchar max_host_qng;
1142 uchar max_dvc_qng;
1143 ushort dvc_cntl;
1144 ushort sdtr_speed4;
1145 ushort serial_number_word1;
1146 ushort serial_number_word2;
1147 ushort serial_number_word3;
1148 ushort check_sum;
1149 uchar oem_name[16];
1150 ushort dvc_err_code;
1151 ushort adv_err_code;
1152 ushort adv_err_addr;
1153 ushort saved_dvc_err_code;
1154 ushort saved_adv_err_code;
1155 ushort saved_adv_err_addr;
1156 ushort reserved36;
1157 ushort reserved37;
1158 ushort reserved38;
1159 ushort reserved39;
1160 ushort reserved40;
1161 ushort reserved41;
1162 ushort reserved42;
1163 ushort reserved43;
1164 ushort reserved44;
1165 ushort reserved45;
1166 ushort reserved46;
1167 ushort reserved47;
1168 ushort reserved48;
1169 ushort reserved49;
1170 ushort reserved50;
1171 ushort reserved51;
1172 ushort reserved52;
1173 ushort reserved53;
1174 ushort reserved54;
1175 ushort reserved55;
1176 ushort cisptr_lsw;
1177 ushort cisprt_msw;
1178 ushort subsysvid;
1179 ushort subsysid;
1180 ushort reserved60;
1181 ushort reserved61;
1182 ushort reserved62;
1183 ushort reserved63;
1184} ADVEEP_38C1600_CONFIG;
1185
1186
1187
1188
1189#define ASC_EEP_CMD_DONE 0x0200
1190
1191
1192#define BIOS_CTRL_BIOS 0x0001
1193#define BIOS_CTRL_EXTENDED_XLAT 0x0002
1194#define BIOS_CTRL_GT_2_DISK 0x0004
1195#define BIOS_CTRL_BIOS_REMOVABLE 0x0008
1196#define BIOS_CTRL_BOOTABLE_CD 0x0010
1197#define BIOS_CTRL_MULTIPLE_LUN 0x0040
1198#define BIOS_CTRL_DISPLAY_MSG 0x0080
1199#define BIOS_CTRL_NO_SCAM 0x0100
1200#define BIOS_CTRL_RESET_SCSI_BUS 0x0200
1201#define BIOS_CTRL_INIT_VERBOSE 0x0800
1202#define BIOS_CTRL_SCSI_PARITY 0x1000
1203#define BIOS_CTRL_AIPP_DIS 0x2000
1204
1205#define ADV_3550_MEMSIZE 0x2000
1206
1207#define ADV_38C0800_MEMSIZE 0x4000
1208
1209
1210
1211
1212
1213
1214
1215
1216#define ADV_38C1600_MEMSIZE 0x4000
1217
1218
1219
1220
1221#define IOPB_INTR_STATUS_REG 0x00
1222#define IOPB_CHIP_ID_1 0x01
1223#define IOPB_INTR_ENABLES 0x02
1224#define IOPB_CHIP_TYPE_REV 0x03
1225#define IOPB_RES_ADDR_4 0x04
1226#define IOPB_RES_ADDR_5 0x05
1227#define IOPB_RAM_DATA 0x06
1228#define IOPB_RES_ADDR_7 0x07
1229#define IOPB_FLAG_REG 0x08
1230#define IOPB_RES_ADDR_9 0x09
1231#define IOPB_RISC_CSR 0x0A
1232#define IOPB_RES_ADDR_B 0x0B
1233#define IOPB_RES_ADDR_C 0x0C
1234#define IOPB_RES_ADDR_D 0x0D
1235#define IOPB_SOFT_OVER_WR 0x0E
1236#define IOPB_RES_ADDR_F 0x0F
1237#define IOPB_MEM_CFG 0x10
1238#define IOPB_RES_ADDR_11 0x11
1239#define IOPB_GPIO_DATA 0x12
1240#define IOPB_RES_ADDR_13 0x13
1241#define IOPB_FLASH_PAGE 0x14
1242#define IOPB_RES_ADDR_15 0x15
1243#define IOPB_GPIO_CNTL 0x16
1244#define IOPB_RES_ADDR_17 0x17
1245#define IOPB_FLASH_DATA 0x18
1246#define IOPB_RES_ADDR_19 0x19
1247#define IOPB_RES_ADDR_1A 0x1A
1248#define IOPB_RES_ADDR_1B 0x1B
1249#define IOPB_RES_ADDR_1C 0x1C
1250#define IOPB_RES_ADDR_1D 0x1D
1251#define IOPB_RES_ADDR_1E 0x1E
1252#define IOPB_RES_ADDR_1F 0x1F
1253#define IOPB_DMA_CFG0 0x20
1254#define IOPB_DMA_CFG1 0x21
1255#define IOPB_TICKLE 0x22
1256#define IOPB_DMA_REG_WR 0x23
1257#define IOPB_SDMA_STATUS 0x24
1258#define IOPB_SCSI_BYTE_CNT 0x25
1259#define IOPB_HOST_BYTE_CNT 0x26
1260#define IOPB_BYTE_LEFT_TO_XFER 0x27
1261#define IOPB_BYTE_TO_XFER_0 0x28
1262#define IOPB_BYTE_TO_XFER_1 0x29
1263#define IOPB_BYTE_TO_XFER_2 0x2A
1264#define IOPB_BYTE_TO_XFER_3 0x2B
1265#define IOPB_ACC_GRP 0x2C
1266#define IOPB_RES_ADDR_2D 0x2D
1267#define IOPB_DEV_ID 0x2E
1268#define IOPB_RES_ADDR_2F 0x2F
1269#define IOPB_SCSI_DATA 0x30
1270#define IOPB_RES_ADDR_31 0x31
1271#define IOPB_RES_ADDR_32 0x32
1272#define IOPB_SCSI_DATA_HSHK 0x33
1273#define IOPB_SCSI_CTRL 0x34
1274#define IOPB_RES_ADDR_35 0x35
1275#define IOPB_RES_ADDR_36 0x36
1276#define IOPB_RES_ADDR_37 0x37
1277#define IOPB_RAM_BIST 0x38
1278#define IOPB_PLL_TEST 0x39
1279#define IOPB_PCI_INT_CFG 0x3A
1280#define IOPB_RES_ADDR_3B 0x3B
1281#define IOPB_RFIFO_CNT 0x3C
1282#define IOPB_RES_ADDR_3D 0x3D
1283#define IOPB_RES_ADDR_3E 0x3E
1284#define IOPB_RES_ADDR_3F 0x3F
1285
1286
1287
1288
1289#define IOPW_CHIP_ID_0 0x00
1290#define IOPW_CTRL_REG 0x02
1291#define IOPW_RAM_ADDR 0x04
1292#define IOPW_RAM_DATA 0x06
1293#define IOPW_RES_ADDR_08 0x08
1294#define IOPW_RISC_CSR 0x0A
1295#define IOPW_SCSI_CFG0 0x0C
1296#define IOPW_SCSI_CFG1 0x0E
1297#define IOPW_RES_ADDR_10 0x10
1298#define IOPW_SEL_MASK 0x12
1299#define IOPW_RES_ADDR_14 0x14
1300#define IOPW_FLASH_ADDR 0x16
1301#define IOPW_RES_ADDR_18 0x18
1302#define IOPW_EE_CMD 0x1A
1303#define IOPW_EE_DATA 0x1C
1304#define IOPW_SFIFO_CNT 0x1E
1305#define IOPW_RES_ADDR_20 0x20
1306#define IOPW_Q_BASE 0x22
1307#define IOPW_QP 0x24
1308#define IOPW_IX 0x26
1309#define IOPW_SP 0x28
1310#define IOPW_PC 0x2A
1311#define IOPW_RES_ADDR_2C 0x2C
1312#define IOPW_RES_ADDR_2E 0x2E
1313#define IOPW_SCSI_DATA 0x30
1314#define IOPW_SCSI_DATA_HSHK 0x32
1315#define IOPW_SCSI_CTRL 0x34
1316#define IOPW_HSHK_CFG 0x36
1317#define IOPW_SXFR_STATUS 0x36
1318#define IOPW_SXFR_CNTL 0x38
1319#define IOPW_SXFR_CNTH 0x3A
1320#define IOPW_RES_ADDR_3C 0x3C
1321#define IOPW_RFIFO_DATA 0x3E
1322
1323
1324
1325
1326#define IOPDW_RES_ADDR_0 0x00
1327#define IOPDW_RAM_DATA 0x04
1328#define IOPDW_RES_ADDR_8 0x08
1329#define IOPDW_RES_ADDR_C 0x0C
1330#define IOPDW_RES_ADDR_10 0x10
1331#define IOPDW_COMMA 0x14
1332#define IOPDW_COMMB 0x18
1333#define IOPDW_RES_ADDR_1C 0x1C
1334#define IOPDW_SDMA_ADDR0 0x20
1335#define IOPDW_SDMA_ADDR1 0x24
1336#define IOPDW_SDMA_COUNT 0x28
1337#define IOPDW_SDMA_ERROR 0x2C
1338#define IOPDW_RDMA_ADDR0 0x30
1339#define IOPDW_RDMA_ADDR1 0x34
1340#define IOPDW_RDMA_COUNT 0x38
1341#define IOPDW_RDMA_ERROR 0x3C
1342
1343#define ADV_CHIP_ID_BYTE 0x25
1344#define ADV_CHIP_ID_WORD 0x04C1
1345
1346#define ADV_INTR_ENABLE_HOST_INTR 0x01
1347#define ADV_INTR_ENABLE_SEL_INTR 0x02
1348#define ADV_INTR_ENABLE_DPR_INTR 0x04
1349#define ADV_INTR_ENABLE_RTA_INTR 0x08
1350#define ADV_INTR_ENABLE_RMA_INTR 0x10
1351#define ADV_INTR_ENABLE_RST_INTR 0x20
1352#define ADV_INTR_ENABLE_DPE_INTR 0x40
1353#define ADV_INTR_ENABLE_GLOBAL_INTR 0x80
1354
1355#define ADV_INTR_STATUS_INTRA 0x01
1356#define ADV_INTR_STATUS_INTRB 0x02
1357#define ADV_INTR_STATUS_INTRC 0x04
1358
1359#define ADV_RISC_CSR_STOP (0x0000)
1360#define ADV_RISC_TEST_COND (0x2000)
1361#define ADV_RISC_CSR_RUN (0x4000)
1362#define ADV_RISC_CSR_SINGLE_STEP (0x8000)
1363
1364#define ADV_CTRL_REG_HOST_INTR 0x0100
1365#define ADV_CTRL_REG_SEL_INTR 0x0200
1366#define ADV_CTRL_REG_DPR_INTR 0x0400
1367#define ADV_CTRL_REG_RTA_INTR 0x0800
1368#define ADV_CTRL_REG_RMA_INTR 0x1000
1369#define ADV_CTRL_REG_RES_BIT14 0x2000
1370#define ADV_CTRL_REG_DPE_INTR 0x4000
1371#define ADV_CTRL_REG_POWER_DONE 0x8000
1372#define ADV_CTRL_REG_ANY_INTR 0xFF00
1373
1374#define ADV_CTRL_REG_CMD_RESET 0x00C6
1375#define ADV_CTRL_REG_CMD_WR_IO_REG 0x00C5
1376#define ADV_CTRL_REG_CMD_RD_IO_REG 0x00C4
1377#define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE 0x00C3
1378#define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE 0x00C2
1379
1380#define ADV_TICKLE_NOP 0x00
1381#define ADV_TICKLE_A 0x01
1382#define ADV_TICKLE_B 0x02
1383#define ADV_TICKLE_C 0x03
1384
1385#define AdvIsIntPending(port) \
1386 (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
1387
1388
1389
1390
1391#define TIMER_MODEAB 0xC000
1392#define PARITY_EN 0x2000
1393#define EVEN_PARITY 0x1000
1394#define WD_LONG 0x0800
1395#define QUEUE_128 0x0400
1396#define PRIM_MODE 0x0100
1397#define SCAM_EN 0x0080
1398#define SEL_TMO_LONG 0x0040
1399#define CFRM_ID 0x0020
1400#define OUR_ID_EN 0x0010
1401#define OUR_ID 0x000F
1402
1403
1404
1405
1406#define BIG_ENDIAN 0x8000
1407#define TERM_POL 0x2000
1408#define SLEW_RATE 0x1000
1409#define FILTER_SEL 0x0C00
1410#define FLTR_DISABLE 0x0000
1411#define FLTR_11_TO_20NS 0x0800
1412#define FLTR_21_TO_39NS 0x0C00
1413#define ACTIVE_DBL 0x0200
1414#define DIFF_MODE 0x0100
1415#define DIFF_SENSE 0x0080
1416#define TERM_CTL_SEL 0x0040
1417#define TERM_CTL 0x0030
1418#define TERM_CTL_H 0x0020
1419#define TERM_CTL_L 0x0010
1420#define CABLE_DETECT 0x000F
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433#define DIS_TERM_DRV 0x4000
1434#define HVD_LVD_SE 0x1C00
1435#define HVD 0x1000
1436#define LVD 0x0800
1437#define SE 0x0400
1438#define TERM_LVD 0x00C0
1439#define TERM_LVD_HI 0x0080
1440#define TERM_LVD_LO 0x0040
1441#define TERM_SE 0x0030
1442#define TERM_SE_HI 0x0020
1443#define TERM_SE_LO 0x0010
1444#define C_DET_LVD 0x000C
1445#define C_DET3 0x0008
1446#define C_DET2 0x0004
1447#define C_DET_SE 0x0003
1448#define C_DET1 0x0002
1449#define C_DET0 0x0001
1450
1451#define CABLE_ILLEGAL_A 0x7
1452
1453
1454#define CABLE_ILLEGAL_B 0xB
1455
1456
1457
1458
1459
1460#define BIOS_EN 0x40
1461#define FAST_EE_CLK 0x20
1462#define RAM_SZ 0x1C
1463#define RAM_SZ_2KB 0x00
1464#define RAM_SZ_4KB 0x04
1465#define RAM_SZ_8KB 0x08
1466#define RAM_SZ_16KB 0x0C
1467#define RAM_SZ_32KB 0x10
1468#define RAM_SZ_64KB 0x14
1469
1470
1471
1472
1473
1474
1475#define BC_THRESH_ENB 0x80
1476#define FIFO_THRESH 0x70
1477#define FIFO_THRESH_16B 0x00
1478#define FIFO_THRESH_32B 0x20
1479#define FIFO_THRESH_48B 0x30
1480#define FIFO_THRESH_64B 0x40
1481#define FIFO_THRESH_80B 0x50
1482#define FIFO_THRESH_96B 0x60
1483#define FIFO_THRESH_112B 0x70
1484#define START_CTL 0x0C
1485#define START_CTL_TH 0x00
1486#define START_CTL_ID 0x04
1487#define START_CTL_THID 0x08
1488#define START_CTL_EMFU 0x0C
1489#define READ_CMD 0x03
1490#define READ_CMD_MR 0x00
1491#define READ_CMD_MRL 0x02
1492#define READ_CMD_MRM 0x03
1493
1494
1495
1496
1497#define RAM_TEST_MODE 0x80
1498#define PRE_TEST_MODE 0x40
1499#define NORMAL_MODE 0x00
1500#define RAM_TEST_DONE 0x10
1501#define RAM_TEST_STATUS 0x0F
1502#define RAM_TEST_HOST_ERROR 0x08
1503#define RAM_TEST_INTRAM_ERROR 0x04
1504#define RAM_TEST_RISC_ERROR 0x02
1505#define RAM_TEST_SCSI_ERROR 0x01
1506#define RAM_TEST_SUCCESS 0x00
1507#define PRE_TEST_VALUE 0x05
1508#define NORMAL_VALUE 0x00
1509
1510
1511
1512
1513
1514
1515
1516#define INTAB_LD 0x80
1517
1518
1519
1520
1521
1522
1523
1524#define TOTEMPOLE 0x02
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535#define INTAB 0x01
1536
1537
1538
1539
1540#define ADV_TRUE 1
1541#define ADV_FALSE 0
1542#define ADV_SUCCESS 1
1543#define ADV_BUSY 0
1544#define ADV_ERROR (-1)
1545
1546
1547
1548
1549#define ASC_WARN_BUSRESET_ERROR 0x0001
1550#define ASC_WARN_EEPROM_CHKSUM 0x0002
1551#define ASC_WARN_EEPROM_TERMINATION 0x0004
1552#define ASC_WARN_ERROR 0xFFFF
1553
1554#define ADV_MAX_TID 15
1555#define ADV_MAX_LUN 7
1556
1557
1558
1559
1560#define ASC_MC_CODE_BEGIN_ADDR 0x0028
1561#define ASC_MC_CODE_END_ADDR 0x002A
1562#define ASC_MC_CODE_CHK_SUM 0x002C
1563#define ASC_MC_VERSION_DATE 0x0038
1564#define ASC_MC_VERSION_NUM 0x003A
1565#define ASC_MC_BIOSMEM 0x0040
1566#define ASC_MC_BIOSLEN 0x0050
1567#define ASC_MC_BIOS_SIGNATURE 0x0058
1568#define ASC_MC_BIOS_VERSION 0x005A
1569#define ASC_MC_SDTR_SPEED1 0x0090
1570#define ASC_MC_SDTR_SPEED2 0x0092
1571#define ASC_MC_SDTR_SPEED3 0x0094
1572#define ASC_MC_SDTR_SPEED4 0x0096
1573#define ASC_MC_CHIP_TYPE 0x009A
1574#define ASC_MC_INTRB_CODE 0x009B
1575#define ASC_MC_WDTR_ABLE 0x009C
1576#define ASC_MC_SDTR_ABLE 0x009E
1577#define ASC_MC_TAGQNG_ABLE 0x00A0
1578#define ASC_MC_DISC_ENABLE 0x00A2
1579#define ASC_MC_IDLE_CMD_STATUS 0x00A4
1580#define ASC_MC_IDLE_CMD 0x00A6
1581#define ASC_MC_IDLE_CMD_PARAMETER 0x00A8
1582#define ASC_MC_DEFAULT_SCSI_CFG0 0x00AC
1583#define ASC_MC_DEFAULT_SCSI_CFG1 0x00AE
1584#define ASC_MC_DEFAULT_MEM_CFG 0x00B0
1585#define ASC_MC_DEFAULT_SEL_MASK 0x00B2
1586#define ASC_MC_SDTR_DONE 0x00B6
1587#define ASC_MC_NUMBER_OF_QUEUED_CMD 0x00C0
1588#define ASC_MC_NUMBER_OF_MAX_CMD 0x00D0
1589#define ASC_MC_DEVICE_HSHK_CFG_TABLE 0x0100
1590#define ASC_MC_CONTROL_FLAG 0x0122
1591#define ASC_MC_WDTR_DONE 0x0124
1592#define ASC_MC_CAM_MODE_MASK 0x015E
1593#define ASC_MC_ICQ 0x0160
1594#define ASC_MC_IRQ 0x0164
1595#define ASC_MC_PPR_ABLE 0x017A
1596
1597
1598
1599
1600#define BIOS_CODESEG 0x54
1601#define BIOS_CODELEN 0x56
1602#define BIOS_SIGNATURE 0x58
1603#define BIOS_VERSION 0x5A
1604
1605
1606
1607
1608
1609
1610
1611#define CONTROL_FLAG_IGNORE_PERR 0x0001
1612#define CONTROL_FLAG_ENABLE_AIPP 0x0002
1613
1614
1615
1616
1617#define HSHK_CFG_WIDE_XFR 0x8000
1618#define HSHK_CFG_RATE 0x0F00
1619#define HSHK_CFG_OFFSET 0x001F
1620
1621#define ASC_DEF_MAX_HOST_QNG 0xFD
1622#define ASC_DEF_MIN_HOST_QNG 0x10
1623#define ASC_DEF_MAX_DVC_QNG 0x3F
1624#define ASC_DEF_MIN_DVC_QNG 0x04
1625
1626#define ASC_QC_DATA_CHECK 0x01
1627#define ASC_QC_DATA_OUT 0x02
1628#define ASC_QC_START_MOTOR 0x04
1629#define ASC_QC_NO_OVERRUN 0x08
1630#define ASC_QC_FREEZE_TIDQ 0x10
1631
1632#define ASC_QSC_NO_DISC 0x01
1633#define ASC_QSC_NO_TAGMSG 0x02
1634#define ASC_QSC_NO_SYNC 0x04
1635#define ASC_QSC_NO_WIDE 0x08
1636#define ASC_QSC_REDO_DTR 0x10
1637
1638
1639
1640
1641#define ASC_QSC_HEAD_TAG 0x40
1642#define ASC_QSC_ORDERED_TAG 0x80
1643
1644
1645
1646
1647
1648typedef struct adv_carr_t {
1649 __le32 carr_va;
1650 __le32 carr_pa;
1651 __le32 areq_vpa;
1652
1653
1654
1655
1656
1657
1658 __le32 next_vpa;
1659} ADV_CARR_T;
1660
1661
1662
1663
1664#define ADV_NEXT_VPA_MASK 0xFFFFFFF0
1665
1666#define ADV_RQ_DONE 0x00000001
1667#define ADV_RQ_GOOD 0x00000002
1668#define ADV_CQ_STOPPER 0x00000000
1669
1670#define ADV_GET_CARRP(carrp) ((carrp) & ADV_NEXT_VPA_MASK)
1671
1672
1673
1674
1675
1676#define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 3)
1677
1678#define ADV_CARRIER_BUFSIZE \
1679 (ADV_CARRIER_COUNT * sizeof(ADV_CARR_T))
1680
1681#define ADV_CHIP_ASC3550 0x01
1682#define ADV_CHIP_ASC38C0800 0x02
1683#define ADV_CHIP_ASC38C1600 0x03
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696typedef struct adv_dvc_cfg {
1697 ushort disc_enable;
1698 uchar chip_version;
1699 uchar termination;
1700 ushort control_flag;
1701 ushort mcode_date;
1702 ushort mcode_version;
1703 ushort serial1;
1704 ushort serial2;
1705 ushort serial3;
1706} ADV_DVC_CFG;
1707
1708struct adv_dvc_var;
1709struct adv_scsi_req_q;
1710
1711typedef struct adv_sg_block {
1712 uchar reserved1;
1713 uchar reserved2;
1714 uchar reserved3;
1715 uchar sg_cnt;
1716 __le32 sg_ptr;
1717 struct {
1718 __le32 sg_addr;
1719 __le32 sg_count;
1720 } sg_list[NO_OF_SG_PER_BLOCK];
1721} ADV_SG_BLOCK;
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734typedef struct adv_scsi_req_q {
1735 uchar cntl;
1736 uchar target_cmd;
1737 uchar target_id;
1738 uchar target_lun;
1739 __le32 data_addr;
1740 __le32 data_cnt;
1741 __le32 sense_addr;
1742 __le32 carr_pa;
1743 uchar mflag;
1744 uchar sense_len;
1745 uchar cdb_len;
1746 uchar scsi_cntl;
1747 uchar done_status;
1748 uchar scsi_status;
1749 uchar host_status;
1750 uchar sg_working_ix;
1751 uchar cdb[12];
1752 __le32 sg_real_addr;
1753 __le32 scsiq_rptr;
1754 uchar cdb16[4];
1755 __le32 scsiq_ptr;
1756 __le32 carr_va;
1757
1758
1759
1760
1761 u32 srb_tag;
1762 ADV_SG_BLOCK *sg_list_ptr;
1763} ADV_SCSI_REQ_Q;
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780typedef struct adv_sgblk {
1781 ADV_SG_BLOCK sg_block;
1782 dma_addr_t sg_addr;
1783 struct adv_sgblk *next_sgblkp;
1784} adv_sgblk_t;
1785
1786typedef struct adv_req {
1787 ADV_SCSI_REQ_Q scsi_req_q;
1788 uchar align[24];
1789 struct scsi_cmnd *cmndp;
1790 dma_addr_t req_addr;
1791 adv_sgblk_t *sgblkp;
1792} adv_req_t __aligned(32);
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806typedef struct adv_dvc_var {
1807 AdvPortAddr iop_base;
1808 ushort err_code;
1809 ushort bios_ctrl;
1810 ushort wdtr_able;
1811 ushort sdtr_able;
1812 ushort ultra_able;
1813 ushort sdtr_speed1;
1814 ushort sdtr_speed2;
1815 ushort sdtr_speed3;
1816 ushort sdtr_speed4;
1817 ushort tagqng_able;
1818 ushort ppr_able;
1819 uchar max_dvc_qng;
1820 ushort start_motor;
1821 uchar scsi_reset_wait;
1822 uchar chip_no;
1823 uchar max_host_qng;
1824 ushort no_scam;
1825 struct asc_board *drv_ptr;
1826 uchar chip_scsi_id;
1827 uchar chip_type;
1828 uchar bist_err_code;
1829 ADV_CARR_T *carrier;
1830 ADV_CARR_T *carr_freelist;
1831 dma_addr_t carrier_addr;
1832 ADV_CARR_T *icq_sp;
1833 ADV_CARR_T *irq_sp;
1834 ushort carr_pending_cnt;
1835
1836
1837
1838
1839 ADV_DVC_CFG *cfg;
1840} ADV_DVC_VAR;
1841
1842
1843
1844
1845#define IDLE_CMD_COMPLETED 0
1846#define IDLE_CMD_STOP_CHIP 0x0001
1847#define IDLE_CMD_STOP_CHIP_SEND_INT 0x0002
1848#define IDLE_CMD_SEND_INT 0x0004
1849#define IDLE_CMD_ABORT 0x0008
1850#define IDLE_CMD_DEVICE_RESET 0x0010
1851#define IDLE_CMD_SCSI_RESET_START 0x0020
1852#define IDLE_CMD_SCSI_RESET_END 0x0040
1853#define IDLE_CMD_SCSIREQ 0x0080
1854
1855#define IDLE_CMD_STATUS_SUCCESS 0x0001
1856#define IDLE_CMD_STATUS_FAILURE 0x0002
1857
1858
1859
1860
1861#define ADV_NOWAIT 0x01
1862
1863
1864
1865
1866#define SCSI_WAIT_100_MSEC 100UL
1867#define SCSI_US_PER_MSEC 1000
1868#define SCSI_MAX_RETRY 10
1869
1870#define ADV_ASYNC_RDMA_FAILURE 0x01
1871#define ADV_ASYNC_SCSI_BUS_RESET_DET 0x02
1872#define ADV_ASYNC_CARRIER_READY_FAILURE 0x03
1873#define ADV_RDMA_IN_CARR_AND_Q_INVALID 0x04
1874
1875#define ADV_HOST_SCSI_BUS_RESET 0x80
1876
1877
1878#define AdvReadByteRegister(iop_base, reg_off) \
1879 (ADV_MEM_READB((iop_base) + (reg_off)))
1880
1881
1882#define AdvWriteByteRegister(iop_base, reg_off, byte) \
1883 (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
1884
1885
1886#define AdvReadWordRegister(iop_base, reg_off) \
1887 (ADV_MEM_READW((iop_base) + (reg_off)))
1888
1889
1890#define AdvWriteWordRegister(iop_base, reg_off, word) \
1891 (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
1892
1893
1894#define AdvWriteDWordRegister(iop_base, reg_off, dword) \
1895 (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword)))
1896
1897
1898#define AdvReadByteLram(iop_base, addr, byte) \
1899do { \
1900 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
1901 (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
1902} while (0)
1903
1904
1905#define AdvWriteByteLram(iop_base, addr, byte) \
1906 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
1907 ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
1908
1909
1910#define AdvReadWordLram(iop_base, addr, word) \
1911do { \
1912 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
1913 (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
1914} while (0)
1915
1916
1917#define AdvWriteWordLram(iop_base, addr, word) \
1918 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
1919 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
1920
1921
1922
1923#define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \
1924 ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
1925 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
1926 cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
1927 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
1928 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
1929 cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
1930
1931
1932#define AdvReadWordAutoIncLram(iop_base) \
1933 (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
1934
1935
1936#define AdvWriteWordAutoIncLram(iop_base, word) \
1937 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
1938
1939
1940
1941
1942
1943
1944
1945#define AdvFindSignature(iop_base) \
1946 (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
1947 ADV_CHIP_ID_BYTE) && \
1948 (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
1949 ADV_CHIP_ID_WORD)) ? ADV_TRUE : ADV_FALSE)
1950
1951
1952
1953
1954
1955
1956#define AdvGetChipVersion(iop_base, bus_type) \
1957 AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971#define AdvAbortQueue(asc_dvc, srb_tag) \
1972 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
1973 (ADV_DCNT) (srb_tag))
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986#define AdvResetDevice(asc_dvc, target_id) \
1987 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
1988 (ADV_DCNT) (target_id))
1989
1990
1991
1992
1993#define ADV_SCSI_BIT_ID_TYPE ushort
1994
1995
1996
1997
1998#define ADV_SCAN_LUN 0x01
1999#define ADV_CAPINFO_NOLUN 0x02
2000
2001
2002
2003
2004#define ADV_TID_TO_TIDMASK(tid) (0x01 << ((tid) & ADV_MAX_TID))
2005
2006
2007
2008
2009
2010#define QD_NO_STATUS 0x00
2011#define QD_NO_ERROR 0x01
2012#define QD_ABORTED_BY_HOST 0x02
2013#define QD_WITH_ERROR 0x04
2014
2015#define QHSTA_NO_ERROR 0x00
2016#define QHSTA_M_SEL_TIMEOUT 0x11
2017#define QHSTA_M_DATA_OVER_RUN 0x12
2018#define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
2019#define QHSTA_M_QUEUE_ABORTED 0x15
2020#define QHSTA_M_SXFR_SDMA_ERR 0x16
2021#define QHSTA_M_SXFR_SXFR_PERR 0x17
2022#define QHSTA_M_RDMA_PERR 0x18
2023#define QHSTA_M_SXFR_OFF_UFLW 0x19
2024#define QHSTA_M_SXFR_OFF_OFLW 0x20
2025#define QHSTA_M_SXFR_WD_TMO 0x21
2026#define QHSTA_M_SXFR_DESELECTED 0x22
2027
2028#define QHSTA_M_SXFR_XFR_OFLW 0x12
2029#define QHSTA_M_SXFR_XFR_PH_ERR 0x24
2030#define QHSTA_M_SXFR_UNKNOWN_ERROR 0x25
2031#define QHSTA_M_SCSI_BUS_RESET 0x30
2032#define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31
2033#define QHSTA_M_BUS_DEVICE_RESET 0x32
2034#define QHSTA_M_DIRECTION_ERR 0x35
2035#define QHSTA_M_DIRECTION_ERR_HUNG 0x36
2036#define QHSTA_M_WTM_TIMEOUT 0x41
2037#define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
2038#define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
2039#define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
2040#define QHSTA_M_INVALID_DEVICE 0x45
2041#define QHSTA_M_FROZEN_TIDQ 0x46
2042#define QHSTA_M_SGBACKUP_ERROR 0x47
2043
2044
2045#define ADV_32BALIGN(addr) (((ulong) (addr) + 0x1F) & ~0x1F)
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055#define ADV_SG_LIST_MAX_BYTE_SIZE \
2056 (sizeof(ADV_SG_BLOCK) * \
2057 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
2058
2059
2060#define ASC_IS_WIDE_BOARD 0x04
2061
2062#define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
2063
2064#define NO_ISA_DMA 0xff
2065
2066#define ASC_INFO_SIZE 128
2067
2068
2069#define ASC_TRUE 1
2070#define ASC_FALSE 0
2071#define ASC_NOERROR 1
2072#define ASC_BUSY 0
2073#define ASC_ERROR (-1)
2074
2075#define ASC_STATS(shost, counter) ASC_STATS_ADD(shost, counter, 1)
2076#ifndef ADVANSYS_STATS
2077#define ASC_STATS_ADD(shost, counter, count)
2078#else
2079#define ASC_STATS_ADD(shost, counter, count) \
2080 (((struct asc_board *) shost_priv(shost))->asc_stats.counter += (count))
2081#endif
2082
2083
2084#define ASC_TENTHS(num, den) \
2085 (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
2086 0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
2087
2088
2089
2090
2091#define ASC_PRINT(s) \
2092 { \
2093 printk("advansys: "); \
2094 printk(s); \
2095 }
2096
2097#define ASC_PRINT1(s, a1) \
2098 { \
2099 printk("advansys: "); \
2100 printk((s), (a1)); \
2101 }
2102
2103#define ASC_PRINT2(s, a1, a2) \
2104 { \
2105 printk("advansys: "); \
2106 printk((s), (a1), (a2)); \
2107 }
2108
2109#define ASC_PRINT3(s, a1, a2, a3) \
2110 { \
2111 printk("advansys: "); \
2112 printk((s), (a1), (a2), (a3)); \
2113 }
2114
2115#define ASC_PRINT4(s, a1, a2, a3, a4) \
2116 { \
2117 printk("advansys: "); \
2118 printk((s), (a1), (a2), (a3), (a4)); \
2119 }
2120
2121#ifndef ADVANSYS_DEBUG
2122
2123#define ASC_DBG(lvl, s...)
2124#define ASC_DBG_PRT_SCSI_HOST(lvl, s)
2125#define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
2126#define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
2127#define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
2128#define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
2129#define ASC_DBG_PRT_HEX(lvl, name, start, length)
2130#define ASC_DBG_PRT_CDB(lvl, cdb, len)
2131#define ASC_DBG_PRT_SENSE(lvl, sense, len)
2132#define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
2133
2134#else
2135
2136
2137
2138
2139
2140
2141
2142
2143#define ASC_DBG(lvl, format, arg...) { \
2144 if (asc_dbglvl >= (lvl)) \
2145 printk(KERN_DEBUG "%s: %s: " format, DRV_NAME, \
2146 __func__ , ## arg); \
2147}
2148
2149#define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
2150 { \
2151 if (asc_dbglvl >= (lvl)) { \
2152 asc_prt_scsi_host(s); \
2153 } \
2154 }
2155
2156#define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
2157 { \
2158 if (asc_dbglvl >= (lvl)) { \
2159 asc_prt_asc_scsi_q(scsiqp); \
2160 } \
2161 }
2162
2163#define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
2164 { \
2165 if (asc_dbglvl >= (lvl)) { \
2166 asc_prt_asc_qdone_info(qdone); \
2167 } \
2168 }
2169
2170#define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
2171 { \
2172 if (asc_dbglvl >= (lvl)) { \
2173 asc_prt_adv_scsi_req_q(scsiqp); \
2174 } \
2175 }
2176
2177#define ASC_DBG_PRT_HEX(lvl, name, start, length) \
2178 { \
2179 if (asc_dbglvl >= (lvl)) { \
2180 asc_prt_hex((name), (start), (length)); \
2181 } \
2182 }
2183
2184#define ASC_DBG_PRT_CDB(lvl, cdb, len) \
2185 ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
2186
2187#define ASC_DBG_PRT_SENSE(lvl, sense, len) \
2188 ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
2189
2190#define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
2191 ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
2192#endif
2193
2194#ifdef ADVANSYS_STATS
2195
2196
2197struct asc_stats {
2198
2199 unsigned int queuecommand;
2200 unsigned int reset;
2201 unsigned int biosparam;
2202 unsigned int interrupt;
2203 unsigned int callback;
2204 unsigned int done;
2205 unsigned int build_error;
2206 unsigned int adv_build_noreq;
2207 unsigned int adv_build_nosg;
2208
2209 unsigned int exe_noerror;
2210 unsigned int exe_busy;
2211 unsigned int exe_error;
2212 unsigned int exe_unknown;
2213
2214 unsigned int xfer_cnt;
2215 unsigned int xfer_elem;
2216 unsigned int xfer_sect;
2217};
2218#endif
2219
2220
2221
2222
2223
2224
2225
2226
2227struct asc_board {
2228 struct device *dev;
2229 struct Scsi_Host *shost;
2230 uint flags;
2231 unsigned int irq;
2232 union {
2233 ASC_DVC_VAR asc_dvc_var;
2234 ADV_DVC_VAR adv_dvc_var;
2235 } dvc_var;
2236 union {
2237 ASC_DVC_CFG asc_dvc_cfg;
2238 ADV_DVC_CFG adv_dvc_cfg;
2239 } dvc_cfg;
2240 ushort asc_n_io_port;
2241 ADV_SCSI_BIT_ID_TYPE init_tidmask;
2242 ushort reqcnt[ADV_MAX_TID + 1];
2243 ADV_SCSI_BIT_ID_TYPE queue_full;
2244 ushort queue_full_cnt[ADV_MAX_TID + 1];
2245 union {
2246 ASCEEP_CONFIG asc_eep;
2247 ADVEEP_3550_CONFIG adv_3550_eep;
2248 ADVEEP_38C0800_CONFIG adv_38C0800_eep;
2249 ADVEEP_38C1600_CONFIG adv_38C1600_eep;
2250 } eep_config;
2251
2252#ifdef ADVANSYS_STATS
2253 struct asc_stats asc_stats;
2254#endif
2255
2256
2257
2258 uchar sdtr_data[ASC_MAX_TID + 1];
2259
2260
2261
2262 void __iomem *ioremap_addr;
2263 ushort ioport;
2264 adv_req_t *adv_reqp;
2265 dma_addr_t adv_reqp_addr;
2266 size_t adv_reqp_size;
2267 struct dma_pool *adv_sgblk_pool;
2268 ushort bios_signature;
2269 ushort bios_version;
2270 ushort bios_codeseg;
2271 ushort bios_codelen;
2272};
2273
2274#define asc_dvc_to_board(asc_dvc) container_of(asc_dvc, struct asc_board, \
2275 dvc_var.asc_dvc_var)
2276#define adv_dvc_to_board(adv_dvc) container_of(adv_dvc, struct asc_board, \
2277 dvc_var.adv_dvc_var)
2278#define adv_dvc_to_pdev(adv_dvc) to_pci_dev(adv_dvc_to_board(adv_dvc)->dev)
2279
2280#ifdef ADVANSYS_DEBUG
2281static int asc_dbglvl = 3;
2282
2283
2284
2285
2286static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
2287{
2288 printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong)h);
2289
2290 printk(" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl "
2291 "%d,\n", h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
2292
2293 printk(" bus_type %d, init_sdtr 0x%x,\n", h->bus_type,
2294 (unsigned)h->init_sdtr);
2295
2296 printk(" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, "
2297 "chip_no 0x%x,\n", (unsigned)h->sdtr_done,
2298 (unsigned)h->use_tagged_qng, (unsigned)h->unit_not_ready,
2299 (unsigned)h->chip_no);
2300
2301 printk(" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait "
2302 "%u,\n", (unsigned)h->queue_full_or_busy,
2303 (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait);
2304
2305 printk(" is_in_int %u, max_total_qng %u, cur_total_qng %u, "
2306 "in_critical_cnt %u,\n", (unsigned)h->is_in_int,
2307 (unsigned)h->max_total_qng, (unsigned)h->cur_total_qng,
2308 (unsigned)h->in_critical_cnt);
2309
2310 printk(" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, "
2311 "pci_fix_asyn_xfer 0x%x,\n", (unsigned)h->last_q_shortage,
2312 (unsigned)h->init_state, (unsigned)h->no_scam,
2313 (unsigned)h->pci_fix_asyn_xfer);
2314
2315 printk(" cfg 0x%lx\n", (ulong)h->cfg);
2316}
2317
2318
2319
2320
2321static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
2322{
2323 printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong)h);
2324
2325 printk(" can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
2326 h->can_tagged_qng, h->cmd_qng_enabled);
2327 printk(" disc_enable 0x%x, sdtr_enable 0x%x,\n",
2328 h->disc_enable, h->sdtr_enable);
2329
2330 printk(" chip_scsi_id %d, chip_version %d,\n",
2331 h->chip_scsi_id, h->chip_version);
2332
2333 printk(" mcode_date 0x%x, mcode_version %d\n",
2334 h->mcode_date, h->mcode_version);
2335}
2336
2337
2338
2339
2340
2341
2342static void asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
2343{
2344 printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong)h);
2345
2346 printk(" iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
2347 (ulong)h->iop_base, h->err_code, (unsigned)h->ultra_able);
2348
2349 printk(" sdtr_able 0x%x, wdtr_able 0x%x\n",
2350 (unsigned)h->sdtr_able, (unsigned)h->wdtr_able);
2351
2352 printk(" start_motor 0x%x, scsi_reset_wait 0x%x\n",
2353 (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait);
2354
2355 printk(" max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%p\n",
2356 (unsigned)h->max_host_qng, (unsigned)h->max_dvc_qng,
2357 h->carr_freelist);
2358
2359 printk(" icq_sp 0x%p, irq_sp 0x%p\n", h->icq_sp, h->irq_sp);
2360
2361 printk(" no_scam 0x%x, tagqng_able 0x%x\n",
2362 (unsigned)h->no_scam, (unsigned)h->tagqng_able);
2363
2364 printk(" chip_scsi_id 0x%x, cfg 0x%lx\n",
2365 (unsigned)h->chip_scsi_id, (ulong)h->cfg);
2366}
2367
2368
2369
2370
2371
2372
2373static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
2374{
2375 printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong)h);
2376
2377 printk(" disc_enable 0x%x, termination 0x%x\n",
2378 h->disc_enable, h->termination);
2379
2380 printk(" chip_version 0x%x, mcode_date 0x%x\n",
2381 h->chip_version, h->mcode_date);
2382
2383 printk(" mcode_version 0x%x, control_flag 0x%x\n",
2384 h->mcode_version, h->control_flag);
2385}
2386
2387
2388
2389
2390static void asc_prt_scsi_host(struct Scsi_Host *s)
2391{
2392 struct asc_board *boardp = shost_priv(s);
2393
2394 printk("Scsi_Host at addr 0x%p, device %s\n", s, dev_name(boardp->dev));
2395 printk(" host_busy %d, host_no %d,\n",
2396 scsi_host_busy(s), s->host_no);
2397
2398 printk(" base 0x%lx, io_port 0x%lx, irq %d,\n",
2399 (ulong)s->base, (ulong)s->io_port, boardp->irq);
2400
2401 printk(" dma_channel %d, this_id %d, can_queue %d,\n",
2402 s->dma_channel, s->this_id, s->can_queue);
2403
2404 printk(" cmd_per_lun %d, sg_tablesize %d\n",
2405 s->cmd_per_lun, s->sg_tablesize);
2406
2407 if (ASC_NARROW_BOARD(boardp)) {
2408 asc_prt_asc_dvc_var(&boardp->dvc_var.asc_dvc_var);
2409 asc_prt_asc_dvc_cfg(&boardp->dvc_cfg.asc_dvc_cfg);
2410 } else {
2411 asc_prt_adv_dvc_var(&boardp->dvc_var.adv_dvc_var);
2412 asc_prt_adv_dvc_cfg(&boardp->dvc_cfg.adv_dvc_cfg);
2413 }
2414}
2415
2416
2417
2418
2419
2420
2421
2422static void asc_prt_hex(char *f, uchar *s, int l)
2423{
2424 int i;
2425 int j;
2426 int k;
2427 int m;
2428
2429 printk("%s: (%d bytes)\n", f, l);
2430
2431 for (i = 0; i < l; i += 32) {
2432
2433
2434 if ((k = (l - i) / 4) >= 8) {
2435 k = 8;
2436 m = 0;
2437 } else {
2438 m = (l - i) % 4;
2439 }
2440
2441 for (j = 0; j < k; j++) {
2442 printk(" %2.2X%2.2X%2.2X%2.2X",
2443 (unsigned)s[i + (j * 4)],
2444 (unsigned)s[i + (j * 4) + 1],
2445 (unsigned)s[i + (j * 4) + 2],
2446 (unsigned)s[i + (j * 4) + 3]);
2447 }
2448
2449 switch (m) {
2450 case 0:
2451 default:
2452 break;
2453 case 1:
2454 printk(" %2.2X", (unsigned)s[i + (j * 4)]);
2455 break;
2456 case 2:
2457 printk(" %2.2X%2.2X",
2458 (unsigned)s[i + (j * 4)],
2459 (unsigned)s[i + (j * 4) + 1]);
2460 break;
2461 case 3:
2462 printk(" %2.2X%2.2X%2.2X",
2463 (unsigned)s[i + (j * 4) + 1],
2464 (unsigned)s[i + (j * 4) + 2],
2465 (unsigned)s[i + (j * 4) + 3]);
2466 break;
2467 }
2468
2469 printk("\n");
2470 }
2471}
2472
2473
2474
2475
2476static void asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
2477{
2478 ASC_SG_HEAD *sgp;
2479 int i;
2480
2481 printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong)q);
2482
2483 printk
2484 (" target_ix 0x%x, target_lun %u, srb_tag 0x%x, tag_code 0x%x,\n",
2485 q->q2.target_ix, q->q1.target_lun, q->q2.srb_tag,
2486 q->q2.tag_code);
2487
2488 printk
2489 (" data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
2490 (ulong)le32_to_cpu(q->q1.data_addr),
2491 (ulong)le32_to_cpu(q->q1.data_cnt),
2492 (ulong)le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
2493
2494 printk(" cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
2495 (ulong)q->cdbptr, q->q2.cdb_len,
2496 (ulong)q->sg_head, q->q1.sg_queue_cnt);
2497
2498 if (q->sg_head) {
2499 sgp = q->sg_head;
2500 printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong)sgp);
2501 printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt,
2502 sgp->queue_cnt);
2503 for (i = 0; i < sgp->entry_cnt; i++) {
2504 printk(" [%u]: addr 0x%lx, bytes %lu\n",
2505 i, (ulong)le32_to_cpu(sgp->sg_list[i].addr),
2506 (ulong)le32_to_cpu(sgp->sg_list[i].bytes));
2507 }
2508
2509 }
2510}
2511
2512
2513
2514
2515static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
2516{
2517 printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong)q);
2518 printk(" srb_tag 0x%x, target_ix %u, cdb_len %u, tag_code %u,\n",
2519 q->d2.srb_tag, q->d2.target_ix, q->d2.cdb_len,
2520 q->d2.tag_code);
2521 printk
2522 (" done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
2523 q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
2524}
2525
2526
2527
2528
2529
2530
2531static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
2532{
2533 int i;
2534
2535 printk(" ADV_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
2536 (ulong)b, sgblockno);
2537 printk(" sg_cnt %u, sg_ptr 0x%x\n",
2538 b->sg_cnt, (u32)le32_to_cpu(b->sg_ptr));
2539 BUG_ON(b->sg_cnt > NO_OF_SG_PER_BLOCK);
2540 if (b->sg_ptr != 0)
2541 BUG_ON(b->sg_cnt != NO_OF_SG_PER_BLOCK);
2542 for (i = 0; i < b->sg_cnt; i++) {
2543 printk(" [%u]: sg_addr 0x%x, sg_count 0x%x\n",
2544 i, (u32)le32_to_cpu(b->sg_list[i].sg_addr),
2545 (u32)le32_to_cpu(b->sg_list[i].sg_count));
2546 }
2547}
2548
2549
2550
2551
2552
2553
2554static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
2555{
2556 int sg_blk_cnt;
2557 struct adv_sg_block *sg_ptr;
2558 adv_sgblk_t *sgblkp;
2559
2560 printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong)q);
2561
2562 printk(" target_id %u, target_lun %u, srb_tag 0x%x\n",
2563 q->target_id, q->target_lun, q->srb_tag);
2564
2565 printk(" cntl 0x%x, data_addr 0x%lx\n",
2566 q->cntl, (ulong)le32_to_cpu(q->data_addr));
2567
2568 printk(" data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
2569 (ulong)le32_to_cpu(q->data_cnt),
2570 (ulong)le32_to_cpu(q->sense_addr), q->sense_len);
2571
2572 printk
2573 (" cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
2574 q->cdb_len, q->done_status, q->host_status, q->scsi_status);
2575
2576 printk(" sg_working_ix 0x%x, target_cmd %u\n",
2577 q->sg_working_ix, q->target_cmd);
2578
2579 printk(" scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
2580 (ulong)le32_to_cpu(q->scsiq_rptr),
2581 (ulong)le32_to_cpu(q->sg_real_addr), (ulong)q->sg_list_ptr);
2582
2583
2584 if (q->sg_list_ptr != NULL) {
2585 sgblkp = container_of(q->sg_list_ptr, adv_sgblk_t, sg_block);
2586 sg_blk_cnt = 0;
2587 while (sgblkp) {
2588 sg_ptr = &sgblkp->sg_block;
2589 asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
2590 if (sg_ptr->sg_ptr == 0) {
2591 break;
2592 }
2593 sgblkp = sgblkp->next_sgblkp;
2594 sg_blk_cnt++;
2595 }
2596 }
2597}
2598#endif
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609static const char *advansys_info(struct Scsi_Host *shost)
2610{
2611 static char info[ASC_INFO_SIZE];
2612 struct asc_board *boardp = shost_priv(shost);
2613 ASC_DVC_VAR *asc_dvc_varp;
2614 ADV_DVC_VAR *adv_dvc_varp;
2615 char *busname;
2616 char *widename = NULL;
2617
2618 if (ASC_NARROW_BOARD(boardp)) {
2619 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
2620 ASC_DBG(1, "begin\n");
2621
2622 if (asc_dvc_varp->bus_type & ASC_IS_VL) {
2623 busname = "VL";
2624 } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
2625 busname = "EISA";
2626 } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
2627 if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
2628 == ASC_IS_PCI_ULTRA) {
2629 busname = "PCI Ultra";
2630 } else {
2631 busname = "PCI";
2632 }
2633 } else {
2634 busname = "?";
2635 shost_printk(KERN_ERR, shost, "unknown bus "
2636 "type %d\n", asc_dvc_varp->bus_type);
2637 }
2638 sprintf(info,
2639 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
2640 ASC_VERSION, busname, (ulong)shost->io_port,
2641 (ulong)shost->io_port + ASC_IOADR_GAP - 1,
2642 boardp->irq);
2643 } else {
2644
2645
2646
2647
2648
2649
2650
2651 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
2652 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
2653 widename = "Ultra-Wide";
2654 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
2655 widename = "Ultra2-Wide";
2656 } else {
2657 widename = "Ultra3-Wide";
2658 }
2659 sprintf(info,
2660 "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
2661 ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base,
2662 (ulong)adv_dvc_varp->iop_base + boardp->asc_n_io_port - 1, boardp->irq);
2663 }
2664 BUG_ON(strlen(info) >= ASC_INFO_SIZE);
2665 ASC_DBG(1, "end\n");
2666 return info;
2667}
2668
2669#ifdef CONFIG_PROC_FS
2670
2671
2672
2673
2674
2675
2676static void asc_prt_board_devices(struct seq_file *m, struct Scsi_Host *shost)
2677{
2678 struct asc_board *boardp = shost_priv(shost);
2679 int chip_scsi_id;
2680 int i;
2681
2682 seq_printf(m,
2683 "\nDevice Information for AdvanSys SCSI Host %d:\n",
2684 shost->host_no);
2685
2686 if (ASC_NARROW_BOARD(boardp)) {
2687 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
2688 } else {
2689 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
2690 }
2691
2692 seq_puts(m, "Target IDs Detected:");
2693 for (i = 0; i <= ADV_MAX_TID; i++) {
2694 if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i))
2695 seq_printf(m, " %X,", i);
2696 }
2697 seq_printf(m, " (%X=Host Adapter)\n", chip_scsi_id);
2698}
2699
2700
2701
2702
2703static void asc_prt_adv_bios(struct seq_file *m, struct Scsi_Host *shost)
2704{
2705 struct asc_board *boardp = shost_priv(shost);
2706 ushort major, minor, letter;
2707
2708 seq_puts(m, "\nROM BIOS Version: ");
2709
2710
2711
2712
2713
2714 if (boardp->bios_signature != 0x55AA) {
2715 seq_puts(m, "Disabled or Pre-3.1\n"
2716 "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n"
2717 "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
2718 } else {
2719 major = (boardp->bios_version >> 12) & 0xF;
2720 minor = (boardp->bios_version >> 8) & 0xF;
2721 letter = (boardp->bios_version & 0xFF);
2722
2723 seq_printf(m, "%d.%d%c\n",
2724 major, minor,
2725 letter >= 26 ? '?' : letter + 'A');
2726
2727
2728
2729
2730
2731 if (major < 3 || (major <= 3 && minor < 1) ||
2732 (major <= 3 && minor <= 1 && letter < ('I' - 'A'))) {
2733 seq_puts(m, "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n"
2734 "ftp://ftp.connectcom.net/pub\n");
2735 }
2736 }
2737}
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762static int asc_get_eeprom_string(ushort *serialnum, uchar *cp)
2763{
2764 ushort w, num;
2765
2766 if ((serialnum[1] & 0xFE00) != ((ushort)0xAA << 8)) {
2767 return ASC_FALSE;
2768 } else {
2769
2770
2771
2772 w = serialnum[0];
2773
2774
2775 if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
2776
2777 *cp += 0x8;
2778 }
2779 cp++;
2780
2781
2782 *cp++ = 'A' + ((w & 0x1C00) >> 10);
2783
2784
2785 num = w & 0x3FF;
2786 *cp++ = '0' + (num / 100);
2787 num %= 100;
2788 *cp++ = '0' + (num / 10);
2789
2790
2791 *cp++ = 'A' + (num % 10);
2792
2793
2794
2795
2796 w = serialnum[1];
2797
2798
2799
2800
2801
2802
2803
2804 if (serialnum[2] & 0x8000) {
2805 *cp++ = '8' + ((w & 0x1C0) >> 6);
2806 } else {
2807 *cp++ = '0' + ((w & 0x1C0) >> 6);
2808 }
2809
2810
2811 num = w & 0x003F;
2812 *cp++ = '0' + num / 10;
2813 num %= 10;
2814 *cp++ = '0' + num;
2815
2816
2817
2818
2819 w = serialnum[2] & 0x7FFF;
2820
2821
2822 *cp++ = 'A' + (w / 1000);
2823
2824
2825 num = w % 1000;
2826 *cp++ = '0' + num / 100;
2827 num %= 100;
2828 *cp++ = '0' + num / 10;
2829 num %= 10;
2830 *cp++ = '0' + num;
2831
2832 *cp = '\0';
2833 return ASC_TRUE;
2834 }
2835}
2836
2837
2838
2839
2840
2841
2842static void asc_prt_asc_board_eeprom(struct seq_file *m, struct Scsi_Host *shost)
2843{
2844 struct asc_board *boardp = shost_priv(shost);
2845 ASCEEP_CONFIG *ep;
2846 int i;
2847 uchar serialstr[13];
2848
2849 ep = &boardp->eep_config.asc_eep;
2850
2851 seq_printf(m,
2852 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
2853 shost->host_no);
2854
2855 if (asc_get_eeprom_string((ushort *)&ep->adapter_info[0], serialstr)
2856 == ASC_TRUE)
2857 seq_printf(m, " Serial Number: %s\n", serialstr);
2858 else if (ep->adapter_info[5] == 0xBB)
2859 seq_puts(m,
2860 " Default Settings Used for EEPROM-less Adapter.\n");
2861 else
2862 seq_puts(m, " Serial Number Signature Not Present.\n");
2863
2864 seq_printf(m,
2865 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
2866 ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng,
2867 ep->max_tag_qng);
2868
2869 seq_printf(m,
2870 " cntl 0x%x, no_scam 0x%x\n", ep->cntl, ep->no_scam);
2871
2872 seq_puts(m, " Target ID: ");
2873 for (i = 0; i <= ASC_MAX_TID; i++)
2874 seq_printf(m, " %d", i);
2875
2876 seq_puts(m, "\n Disconnects: ");
2877 for (i = 0; i <= ASC_MAX_TID; i++)
2878 seq_printf(m, " %c",
2879 (ep->disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
2880
2881 seq_puts(m, "\n Command Queuing: ");
2882 for (i = 0; i <= ASC_MAX_TID; i++)
2883 seq_printf(m, " %c",
2884 (ep->use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
2885
2886 seq_puts(m, "\n Start Motor: ");
2887 for (i = 0; i <= ASC_MAX_TID; i++)
2888 seq_printf(m, " %c",
2889 (ep->start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
2890
2891 seq_puts(m, "\n Synchronous Transfer:");
2892 for (i = 0; i <= ASC_MAX_TID; i++)
2893 seq_printf(m, " %c",
2894 (ep->init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
2895 seq_putc(m, '\n');
2896}
2897
2898
2899
2900
2901
2902
2903static void asc_prt_adv_board_eeprom(struct seq_file *m, struct Scsi_Host *shost)
2904{
2905 struct asc_board *boardp = shost_priv(shost);
2906 ADV_DVC_VAR *adv_dvc_varp;
2907 int i;
2908 char *termstr;
2909 uchar serialstr[13];
2910 ADVEEP_3550_CONFIG *ep_3550 = NULL;
2911 ADVEEP_38C0800_CONFIG *ep_38C0800 = NULL;
2912 ADVEEP_38C1600_CONFIG *ep_38C1600 = NULL;
2913 ushort word;
2914 ushort *wordp;
2915 ushort sdtr_speed = 0;
2916
2917 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
2918 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
2919 ep_3550 = &boardp->eep_config.adv_3550_eep;
2920 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
2921 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
2922 } else {
2923 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
2924 }
2925
2926 seq_printf(m,
2927 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
2928 shost->host_no);
2929
2930 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
2931 wordp = &ep_3550->serial_number_word1;
2932 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
2933 wordp = &ep_38C0800->serial_number_word1;
2934 } else {
2935 wordp = &ep_38C1600->serial_number_word1;
2936 }
2937
2938 if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE)
2939 seq_printf(m, " Serial Number: %s\n", serialstr);
2940 else
2941 seq_puts(m, " Serial Number Signature Not Present.\n");
2942
2943 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
2944 seq_printf(m,
2945 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
2946 ep_3550->adapter_scsi_id,
2947 ep_3550->max_host_qng, ep_3550->max_dvc_qng);
2948 else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
2949 seq_printf(m,
2950 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
2951 ep_38C0800->adapter_scsi_id,
2952 ep_38C0800->max_host_qng,
2953 ep_38C0800->max_dvc_qng);
2954 else
2955 seq_printf(m,
2956 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
2957 ep_38C1600->adapter_scsi_id,
2958 ep_38C1600->max_host_qng,
2959 ep_38C1600->max_dvc_qng);
2960 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
2961 word = ep_3550->termination;
2962 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
2963 word = ep_38C0800->termination_lvd;
2964 } else {
2965 word = ep_38C1600->termination_lvd;
2966 }
2967 switch (word) {
2968 case 1:
2969 termstr = "Low Off/High Off";
2970 break;
2971 case 2:
2972 termstr = "Low Off/High On";
2973 break;
2974 case 3:
2975 termstr = "Low On/High On";
2976 break;
2977 default:
2978 case 0:
2979 termstr = "Automatic";
2980 break;
2981 }
2982
2983 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
2984 seq_printf(m,
2985 " termination: %u (%s), bios_ctrl: 0x%x\n",
2986 ep_3550->termination, termstr,
2987 ep_3550->bios_ctrl);
2988 else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
2989 seq_printf(m,
2990 " termination: %u (%s), bios_ctrl: 0x%x\n",
2991 ep_38C0800->termination_lvd, termstr,
2992 ep_38C0800->bios_ctrl);
2993 else
2994 seq_printf(m,
2995 " termination: %u (%s), bios_ctrl: 0x%x\n",
2996 ep_38C1600->termination_lvd, termstr,
2997 ep_38C1600->bios_ctrl);
2998
2999 seq_puts(m, " Target ID: ");
3000 for (i = 0; i <= ADV_MAX_TID; i++)
3001 seq_printf(m, " %X", i);
3002 seq_putc(m, '\n');
3003
3004 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3005 word = ep_3550->disc_enable;
3006 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3007 word = ep_38C0800->disc_enable;
3008 } else {
3009 word = ep_38C1600->disc_enable;
3010 }
3011 seq_puts(m, " Disconnects: ");
3012 for (i = 0; i <= ADV_MAX_TID; i++)
3013 seq_printf(m, " %c",
3014 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3015 seq_putc(m, '\n');
3016
3017 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3018 word = ep_3550->tagqng_able;
3019 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3020 word = ep_38C0800->tagqng_able;
3021 } else {
3022 word = ep_38C1600->tagqng_able;
3023 }
3024 seq_puts(m, " Command Queuing: ");
3025 for (i = 0; i <= ADV_MAX_TID; i++)
3026 seq_printf(m, " %c",
3027 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3028 seq_putc(m, '\n');
3029
3030 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3031 word = ep_3550->start_motor;
3032 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3033 word = ep_38C0800->start_motor;
3034 } else {
3035 word = ep_38C1600->start_motor;
3036 }
3037 seq_puts(m, " Start Motor: ");
3038 for (i = 0; i <= ADV_MAX_TID; i++)
3039 seq_printf(m, " %c",
3040 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3041 seq_putc(m, '\n');
3042
3043 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3044 seq_puts(m, " Synchronous Transfer:");
3045 for (i = 0; i <= ADV_MAX_TID; i++)
3046 seq_printf(m, " %c",
3047 (ep_3550->sdtr_able & ADV_TID_TO_TIDMASK(i)) ?
3048 'Y' : 'N');
3049 seq_putc(m, '\n');
3050 }
3051
3052 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3053 seq_puts(m, " Ultra Transfer: ");
3054 for (i = 0; i <= ADV_MAX_TID; i++)
3055 seq_printf(m, " %c",
3056 (ep_3550->ultra_able & ADV_TID_TO_TIDMASK(i))
3057 ? 'Y' : 'N');
3058 seq_putc(m, '\n');
3059 }
3060
3061 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3062 word = ep_3550->wdtr_able;
3063 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3064 word = ep_38C0800->wdtr_able;
3065 } else {
3066 word = ep_38C1600->wdtr_able;
3067 }
3068 seq_puts(m, " Wide Transfer: ");
3069 for (i = 0; i <= ADV_MAX_TID; i++)
3070 seq_printf(m, " %c",
3071 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3072 seq_putc(m, '\n');
3073
3074 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
3075 adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600) {
3076 seq_puts(m, " Synchronous Transfer Speed (Mhz):\n ");
3077 for (i = 0; i <= ADV_MAX_TID; i++) {
3078 char *speed_str;
3079
3080 if (i == 0) {
3081 sdtr_speed = adv_dvc_varp->sdtr_speed1;
3082 } else if (i == 4) {
3083 sdtr_speed = adv_dvc_varp->sdtr_speed2;
3084 } else if (i == 8) {
3085 sdtr_speed = adv_dvc_varp->sdtr_speed3;
3086 } else if (i == 12) {
3087 sdtr_speed = adv_dvc_varp->sdtr_speed4;
3088 }
3089 switch (sdtr_speed & ADV_MAX_TID) {
3090 case 0:
3091 speed_str = "Off";
3092 break;
3093 case 1:
3094 speed_str = " 5";
3095 break;
3096 case 2:
3097 speed_str = " 10";
3098 break;
3099 case 3:
3100 speed_str = " 20";
3101 break;
3102 case 4:
3103 speed_str = " 40";
3104 break;
3105 case 5:
3106 speed_str = " 80";
3107 break;
3108 default:
3109 speed_str = "Unk";
3110 break;
3111 }
3112 seq_printf(m, "%X:%s ", i, speed_str);
3113 if (i == 7)
3114 seq_puts(m, "\n ");
3115 sdtr_speed >>= 4;
3116 }
3117 seq_putc(m, '\n');
3118 }
3119}
3120
3121
3122
3123
3124static void asc_prt_driver_conf(struct seq_file *m, struct Scsi_Host *shost)
3125{
3126 struct asc_board *boardp = shost_priv(shost);
3127
3128 seq_printf(m,
3129 "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
3130 shost->host_no);
3131
3132 seq_printf(m,
3133 " host_busy %d, max_id %u, max_lun %llu, max_channel %u\n",
3134 scsi_host_busy(shost), shost->max_id,
3135 shost->max_lun, shost->max_channel);
3136
3137 seq_printf(m,
3138 " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
3139 shost->unique_id, shost->can_queue, shost->this_id,
3140 shost->sg_tablesize, shost->cmd_per_lun);
3141
3142 seq_printf(m,
3143 " flags 0x%x, last_reset 0x%lx, jiffies 0x%lx, asc_n_io_port 0x%x\n",
3144 boardp->flags, shost->last_reset, jiffies,
3145 boardp->asc_n_io_port);
3146
3147 seq_printf(m, " io_port 0x%lx\n", shost->io_port);
3148}
3149
3150
3151
3152
3153
3154
3155static void asc_prt_asc_board_info(struct seq_file *m, struct Scsi_Host *shost)
3156{
3157 struct asc_board *boardp = shost_priv(shost);
3158 int chip_scsi_id;
3159 ASC_DVC_VAR *v;
3160 ASC_DVC_CFG *c;
3161 int i;
3162 int renegotiate = 0;
3163
3164 v = &boardp->dvc_var.asc_dvc_var;
3165 c = &boardp->dvc_cfg.asc_dvc_cfg;
3166 chip_scsi_id = c->chip_scsi_id;
3167
3168 seq_printf(m,
3169 "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
3170 shost->host_no);
3171
3172 seq_printf(m, " chip_version %u, mcode_date 0x%x, "
3173 "mcode_version 0x%x, err_code %u\n",
3174 c->chip_version, c->mcode_date, c->mcode_version,
3175 v->err_code);
3176
3177
3178 seq_printf(m,
3179 " Total Command Pending: %d\n", v->cur_total_qng);
3180
3181 seq_puts(m, " Command Queuing:");
3182 for (i = 0; i <= ASC_MAX_TID; i++) {
3183 if ((chip_scsi_id == i) ||
3184 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3185 continue;
3186 }
3187 seq_printf(m, " %X:%c",
3188 i,
3189 (v->use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3190 }
3191
3192
3193 seq_puts(m, "\n Command Queue Pending:");
3194 for (i = 0; i <= ASC_MAX_TID; i++) {
3195 if ((chip_scsi_id == i) ||
3196 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3197 continue;
3198 }
3199 seq_printf(m, " %X:%u", i, v->cur_dvc_qng[i]);
3200 }
3201
3202
3203 seq_puts(m, "\n Command Queue Limit:");
3204 for (i = 0; i <= ASC_MAX_TID; i++) {
3205 if ((chip_scsi_id == i) ||
3206 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3207 continue;
3208 }
3209 seq_printf(m, " %X:%u", i, v->max_dvc_qng[i]);
3210 }
3211
3212
3213 seq_puts(m, "\n Command Queue Full:");
3214 for (i = 0; i <= ASC_MAX_TID; i++) {
3215 if ((chip_scsi_id == i) ||
3216 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3217 continue;
3218 }
3219 if (boardp->queue_full & ADV_TID_TO_TIDMASK(i))
3220 seq_printf(m, " %X:Y-%d",
3221 i, boardp->queue_full_cnt[i]);
3222 else
3223 seq_printf(m, " %X:N", i);
3224 }
3225
3226 seq_puts(m, "\n Synchronous Transfer:");
3227 for (i = 0; i <= ASC_MAX_TID; i++) {
3228 if ((chip_scsi_id == i) ||
3229 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3230 continue;
3231 }
3232 seq_printf(m, " %X:%c",
3233 i,
3234 (v->sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3235 }
3236 seq_putc(m, '\n');
3237
3238 for (i = 0; i <= ASC_MAX_TID; i++) {
3239 uchar syn_period_ix;
3240
3241 if ((chip_scsi_id == i) ||
3242 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
3243 ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
3244 continue;
3245 }
3246
3247 seq_printf(m, " %X:", i);
3248
3249 if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0) {
3250 seq_puts(m, " Asynchronous");
3251 } else {
3252 syn_period_ix =
3253 (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index -
3254 1);
3255
3256 seq_printf(m,
3257 " Transfer Period Factor: %d (%d.%d Mhz),",
3258 v->sdtr_period_tbl[syn_period_ix],
3259 250 / v->sdtr_period_tbl[syn_period_ix],
3260 ASC_TENTHS(250,
3261 v->sdtr_period_tbl[syn_period_ix]));
3262
3263 seq_printf(m, " REQ/ACK Offset: %d",
3264 boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET);
3265 }
3266
3267 if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
3268 seq_puts(m, "*\n");
3269 renegotiate = 1;
3270 } else {
3271 seq_putc(m, '\n');
3272 }
3273 }
3274
3275 if (renegotiate) {
3276 seq_puts(m, " * = Re-negotiation pending before next command.\n");
3277 }
3278}
3279
3280
3281
3282
3283
3284
3285static void asc_prt_adv_board_info(struct seq_file *m, struct Scsi_Host *shost)
3286{
3287 struct asc_board *boardp = shost_priv(shost);
3288 int i;
3289 ADV_DVC_VAR *v;
3290 ADV_DVC_CFG *c;
3291 AdvPortAddr iop_base;
3292 ushort chip_scsi_id;
3293 ushort lramword;
3294 uchar lrambyte;
3295 ushort tagqng_able;
3296 ushort sdtr_able, wdtr_able;
3297 ushort wdtr_done, sdtr_done;
3298 ushort period = 0;
3299 int renegotiate = 0;
3300
3301 v = &boardp->dvc_var.adv_dvc_var;
3302 c = &boardp->dvc_cfg.adv_dvc_cfg;
3303 iop_base = v->iop_base;
3304 chip_scsi_id = v->chip_scsi_id;
3305
3306 seq_printf(m,
3307 "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
3308 shost->host_no);
3309
3310 seq_printf(m,
3311 " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
3312 (unsigned long)v->iop_base,
3313 AdvReadWordRegister(iop_base,IOPW_SCSI_CFG1) & CABLE_DETECT,
3314 v->err_code);
3315
3316 seq_printf(m, " chip_version %u, mcode_date 0x%x, "
3317 "mcode_version 0x%x\n", c->chip_version,
3318 c->mcode_date, c->mcode_version);
3319
3320 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
3321 seq_puts(m, " Queuing Enabled:");
3322 for (i = 0; i <= ADV_MAX_TID; i++) {
3323 if ((chip_scsi_id == i) ||
3324 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3325 continue;
3326 }
3327
3328 seq_printf(m, " %X:%c",
3329 i,
3330 (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3331 }
3332
3333 seq_puts(m, "\n Queue Limit:");
3334 for (i = 0; i <= ADV_MAX_TID; i++) {
3335 if ((chip_scsi_id == i) ||
3336 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3337 continue;
3338 }
3339
3340 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i,
3341 lrambyte);
3342
3343 seq_printf(m, " %X:%d", i, lrambyte);
3344 }
3345
3346 seq_puts(m, "\n Command Pending:");
3347 for (i = 0; i <= ADV_MAX_TID; i++) {
3348 if ((chip_scsi_id == i) ||
3349 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3350 continue;
3351 }
3352
3353 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i,
3354 lrambyte);
3355
3356 seq_printf(m, " %X:%d", i, lrambyte);
3357 }
3358 seq_putc(m, '\n');
3359
3360 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
3361 seq_puts(m, " Wide Enabled:");
3362 for (i = 0; i <= ADV_MAX_TID; i++) {
3363 if ((chip_scsi_id == i) ||
3364 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3365 continue;
3366 }
3367
3368 seq_printf(m, " %X:%c",
3369 i,
3370 (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3371 }
3372 seq_putc(m, '\n');
3373
3374 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
3375 seq_puts(m, " Transfer Bit Width:");
3376 for (i = 0; i <= ADV_MAX_TID; i++) {
3377 if ((chip_scsi_id == i) ||
3378 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3379 continue;
3380 }
3381
3382 AdvReadWordLram(iop_base,
3383 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
3384 lramword);
3385
3386 seq_printf(m, " %X:%d",
3387 i, (lramword & 0x8000) ? 16 : 8);
3388
3389 if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
3390 (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
3391 seq_putc(m, '*');
3392 renegotiate = 1;
3393 }
3394 }
3395 seq_putc(m, '\n');
3396
3397 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
3398 seq_puts(m, " Synchronous Enabled:");
3399 for (i = 0; i <= ADV_MAX_TID; i++) {
3400 if ((chip_scsi_id == i) ||
3401 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3402 continue;
3403 }
3404
3405 seq_printf(m, " %X:%c",
3406 i,
3407 (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3408 }
3409 seq_putc(m, '\n');
3410
3411 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
3412 for (i = 0; i <= ADV_MAX_TID; i++) {
3413
3414 AdvReadWordLram(iop_base,
3415 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
3416 lramword);
3417 lramword &= ~0x8000;
3418
3419 if ((chip_scsi_id == i) ||
3420 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
3421 ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
3422 continue;
3423 }
3424
3425 seq_printf(m, " %X:", i);
3426
3427 if ((lramword & 0x1F) == 0) {
3428 seq_puts(m, " Asynchronous");
3429 } else {
3430 seq_puts(m, " Transfer Period Factor: ");
3431
3432 if ((lramword & 0x1F00) == 0x1100) {
3433 seq_puts(m, "9 (80.0 Mhz),");
3434 } else if ((lramword & 0x1F00) == 0x1000) {
3435 seq_puts(m, "10 (40.0 Mhz),");
3436 } else {
3437
3438 period = (((lramword >> 8) * 25) + 50) / 4;
3439
3440 if (period == 0) {
3441 seq_printf(m, "%d (? Mhz), ", period);
3442 } else {
3443 seq_printf(m,
3444 "%d (%d.%d Mhz),",
3445 period, 250 / period,
3446 ASC_TENTHS(250, period));
3447 }
3448 }
3449
3450 seq_printf(m, " REQ/ACK Offset: %d",
3451 lramword & 0x1F);
3452 }
3453
3454 if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
3455 seq_puts(m, "*\n");
3456 renegotiate = 1;
3457 } else {
3458 seq_putc(m, '\n');
3459 }
3460 }
3461
3462 if (renegotiate) {
3463 seq_puts(m, " * = Re-negotiation pending before next command.\n");
3464 }
3465}
3466
3467#ifdef ADVANSYS_STATS
3468
3469
3470
3471static void asc_prt_board_stats(struct seq_file *m, struct Scsi_Host *shost)
3472{
3473 struct asc_board *boardp = shost_priv(shost);
3474 struct asc_stats *s = &boardp->asc_stats;
3475
3476 seq_printf(m,
3477 "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n",
3478 shost->host_no);
3479
3480 seq_printf(m,
3481 " queuecommand %u, reset %u, biosparam %u, interrupt %u\n",
3482 s->queuecommand, s->reset, s->biosparam,
3483 s->interrupt);
3484
3485 seq_printf(m,
3486 " callback %u, done %u, build_error %u, build_noreq %u, build_nosg %u\n",
3487 s->callback, s->done, s->build_error,
3488 s->adv_build_noreq, s->adv_build_nosg);
3489
3490 seq_printf(m,
3491 " exe_noerror %u, exe_busy %u, exe_error %u, exe_unknown %u\n",
3492 s->exe_noerror, s->exe_busy, s->exe_error,
3493 s->exe_unknown);
3494
3495
3496
3497
3498 if (s->xfer_cnt > 0) {
3499 seq_printf(m, " xfer_cnt %u, xfer_elem %u, ",
3500 s->xfer_cnt, s->xfer_elem);
3501
3502 seq_printf(m, "xfer_bytes %u.%01u kb\n",
3503 s->xfer_sect / 2, ASC_TENTHS(s->xfer_sect, 2));
3504
3505
3506 seq_printf(m, " avg_num_elem %u.%01u, ",
3507 s->xfer_elem / s->xfer_cnt,
3508 ASC_TENTHS(s->xfer_elem, s->xfer_cnt));
3509
3510 seq_printf(m, "avg_elem_size %u.%01u kb, ",
3511 (s->xfer_sect / 2) / s->xfer_elem,
3512 ASC_TENTHS((s->xfer_sect / 2), s->xfer_elem));
3513
3514 seq_printf(m, "avg_xfer_size %u.%01u kb\n",
3515 (s->xfer_sect / 2) / s->xfer_cnt,
3516 ASC_TENTHS((s->xfer_sect / 2), s->xfer_cnt));
3517 }
3518}
3519#endif
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530static int
3531advansys_show_info(struct seq_file *m, struct Scsi_Host *shost)
3532{
3533 struct asc_board *boardp = shost_priv(shost);
3534
3535 ASC_DBG(1, "begin\n");
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547 seq_printf(m, "%s\n", (char *)advansys_info(shost));
3548
3549
3550
3551 if (!ASC_NARROW_BOARD(boardp))
3552 asc_prt_adv_bios(m, shost);
3553
3554
3555
3556
3557 asc_prt_board_devices(m, shost);
3558
3559
3560
3561
3562 if (ASC_NARROW_BOARD(boardp))
3563 asc_prt_asc_board_eeprom(m, shost);
3564 else
3565 asc_prt_adv_board_eeprom(m, shost);
3566
3567
3568
3569
3570 asc_prt_driver_conf(m, shost);
3571
3572#ifdef ADVANSYS_STATS
3573
3574
3575
3576 asc_prt_board_stats(m, shost);
3577#endif
3578
3579
3580
3581
3582
3583 if (ASC_NARROW_BOARD(boardp))
3584 asc_prt_asc_board_info(m, shost);
3585 else
3586 asc_prt_adv_board_info(m, shost);
3587 return 0;
3588}
3589#endif
3590
3591static void asc_scsi_done(struct scsi_cmnd *scp)
3592{
3593 scsi_dma_unmap(scp);
3594 ASC_STATS(scp->device->host, done);
3595 scp->scsi_done(scp);
3596}
3597
3598static void AscSetBank(PortAddr iop_base, uchar bank)
3599{
3600 uchar val;
3601
3602 val = AscGetChipControl(iop_base) &
3603 (~
3604 (CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET |
3605 CC_CHIP_RESET));
3606 if (bank == 1) {
3607 val |= CC_BANK_ONE;
3608 } else if (bank == 2) {
3609 val |= CC_DIAG | CC_BANK_ONE;
3610 } else {
3611 val &= ~CC_BANK_ONE;
3612 }
3613 AscSetChipControl(iop_base, val);
3614}
3615
3616static void AscSetChipIH(PortAddr iop_base, ushort ins_code)
3617{
3618 AscSetBank(iop_base, 1);
3619 AscWriteChipIH(iop_base, ins_code);
3620 AscSetBank(iop_base, 0);
3621}
3622
3623static int AscStartChip(PortAddr iop_base)
3624{
3625 AscSetChipControl(iop_base, 0);
3626 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
3627 return (0);
3628 }
3629 return (1);
3630}
3631
3632static bool AscStopChip(PortAddr iop_base)
3633{
3634 uchar cc_val;
3635
3636 cc_val =
3637 AscGetChipControl(iop_base) &
3638 (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
3639 AscSetChipControl(iop_base, (uchar)(cc_val | CC_HALT));
3640 AscSetChipIH(iop_base, INS_HALT);
3641 AscSetChipIH(iop_base, INS_RFLAG_WTM);
3642 if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
3643 return false;
3644 }
3645 return true;
3646}
3647
3648static bool AscIsChipHalted(PortAddr iop_base)
3649{
3650 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
3651 if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
3652 return true;
3653 }
3654 }
3655 return false;
3656}
3657
3658static bool AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc)
3659{
3660 PortAddr iop_base;
3661 int i = 10;
3662
3663 iop_base = asc_dvc->iop_base;
3664 while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE)
3665 && (i-- > 0)) {
3666 mdelay(100);
3667 }
3668 AscStopChip(iop_base);
3669 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
3670 udelay(60);
3671 AscSetChipIH(iop_base, INS_RFLAG_WTM);
3672 AscSetChipIH(iop_base, INS_HALT);
3673 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
3674 AscSetChipControl(iop_base, CC_HALT);
3675 mdelay(200);
3676 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
3677 AscSetChipStatus(iop_base, 0);
3678 return (AscIsChipHalted(iop_base));
3679}
3680
3681static int AscFindSignature(PortAddr iop_base)
3682{
3683 ushort sig_word;
3684
3685 ASC_DBG(1, "AscGetChipSignatureByte(0x%x) 0x%x\n",
3686 iop_base, AscGetChipSignatureByte(iop_base));
3687 if (AscGetChipSignatureByte(iop_base) == (uchar)ASC_1000_ID1B) {
3688 ASC_DBG(1, "AscGetChipSignatureWord(0x%x) 0x%x\n",
3689 iop_base, AscGetChipSignatureWord(iop_base));
3690 sig_word = AscGetChipSignatureWord(iop_base);
3691 if ((sig_word == (ushort)ASC_1000_ID0W) ||
3692 (sig_word == (ushort)ASC_1000_ID0W_FIX)) {
3693 return (1);
3694 }
3695 }
3696 return (0);
3697}
3698
3699static void AscEnableInterrupt(PortAddr iop_base)
3700{
3701 ushort cfg;
3702
3703 cfg = AscGetChipCfgLsw(iop_base);
3704 AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
3705}
3706
3707static void AscDisableInterrupt(PortAddr iop_base)
3708{
3709 ushort cfg;
3710
3711 cfg = AscGetChipCfgLsw(iop_base);
3712 AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
3713}
3714
3715static uchar AscReadLramByte(PortAddr iop_base, ushort addr)
3716{
3717 unsigned char byte_data;
3718 unsigned short word_data;
3719
3720 if (isodd_word(addr)) {
3721 AscSetChipLramAddr(iop_base, addr - 1);
3722 word_data = AscGetChipLramData(iop_base);
3723 byte_data = (word_data >> 8) & 0xFF;
3724 } else {
3725 AscSetChipLramAddr(iop_base, addr);
3726 word_data = AscGetChipLramData(iop_base);
3727 byte_data = word_data & 0xFF;
3728 }
3729 return byte_data;
3730}
3731
3732static ushort AscReadLramWord(PortAddr iop_base, ushort addr)
3733{
3734 ushort word_data;
3735
3736 AscSetChipLramAddr(iop_base, addr);
3737 word_data = AscGetChipLramData(iop_base);
3738 return (word_data);
3739}
3740
3741static void
3742AscMemWordSetLram(PortAddr iop_base, ushort s_addr, ushort set_wval, int words)
3743{
3744 int i;
3745
3746 AscSetChipLramAddr(iop_base, s_addr);
3747 for (i = 0; i < words; i++) {
3748 AscSetChipLramData(iop_base, set_wval);
3749 }
3750}
3751
3752static void AscWriteLramWord(PortAddr iop_base, ushort addr, ushort word_val)
3753{
3754 AscSetChipLramAddr(iop_base, addr);
3755 AscSetChipLramData(iop_base, word_val);
3756}
3757
3758static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val)
3759{
3760 ushort word_data;
3761
3762 if (isodd_word(addr)) {
3763 addr--;
3764 word_data = AscReadLramWord(iop_base, addr);
3765 word_data &= 0x00FF;
3766 word_data |= (((ushort)byte_val << 8) & 0xFF00);
3767 } else {
3768 word_data = AscReadLramWord(iop_base, addr);
3769 word_data &= 0xFF00;
3770 word_data |= ((ushort)byte_val & 0x00FF);
3771 }
3772 AscWriteLramWord(iop_base, addr, word_data);
3773}
3774
3775
3776
3777
3778
3779
3780
3781static void
3782AscMemWordCopyPtrToLram(PortAddr iop_base, ushort s_addr,
3783 const uchar *s_buffer, int words)
3784{
3785 int i;
3786
3787 AscSetChipLramAddr(iop_base, s_addr);
3788 for (i = 0; i < 2 * words; i += 2) {
3789
3790
3791
3792
3793
3794
3795
3796
3797 outpw(iop_base + IOP_RAM_DATA,
3798 ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);
3799 }
3800}
3801
3802
3803
3804
3805
3806
3807
3808static void
3809AscMemDWordCopyPtrToLram(PortAddr iop_base,
3810 ushort s_addr, uchar *s_buffer, int dwords)
3811{
3812 int i;
3813
3814 AscSetChipLramAddr(iop_base, s_addr);
3815 for (i = 0; i < 4 * dwords; i += 4) {
3816 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);
3817 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 3] << 8) | s_buffer[i + 2]);
3818 }
3819}
3820
3821
3822
3823
3824
3825
3826
3827static void
3828AscMemWordCopyPtrFromLram(PortAddr iop_base,
3829 ushort s_addr, uchar *d_buffer, int words)
3830{
3831 int i;
3832 ushort word;
3833
3834 AscSetChipLramAddr(iop_base, s_addr);
3835 for (i = 0; i < 2 * words; i += 2) {
3836 word = inpw(iop_base + IOP_RAM_DATA);
3837 d_buffer[i] = word & 0xff;
3838 d_buffer[i + 1] = (word >> 8) & 0xff;
3839 }
3840}
3841
3842static u32 AscMemSumLramWord(PortAddr iop_base, ushort s_addr, int words)
3843{
3844 u32 sum = 0;
3845 int i;
3846
3847 for (i = 0; i < words; i++, s_addr += 2) {
3848 sum += AscReadLramWord(iop_base, s_addr);
3849 }
3850 return (sum);
3851}
3852
3853static void AscInitLram(ASC_DVC_VAR *asc_dvc)
3854{
3855 uchar i;
3856 ushort s_addr;
3857 PortAddr iop_base;
3858
3859 iop_base = asc_dvc->iop_base;
3860 AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
3861 (ushort)(((int)(asc_dvc->max_total_qng + 2 + 1) *
3862 64) >> 1));
3863 i = ASC_MIN_ACTIVE_QNO;
3864 s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
3865 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
3866 (uchar)(i + 1));
3867 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
3868 (uchar)(asc_dvc->max_total_qng));
3869 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
3870 (uchar)i);
3871 i++;
3872 s_addr += ASC_QBLK_SIZE;
3873 for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
3874 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
3875 (uchar)(i + 1));
3876 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
3877 (uchar)(i - 1));
3878 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
3879 (uchar)i);
3880 }
3881 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
3882 (uchar)ASC_QLINK_END);
3883 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
3884 (uchar)(asc_dvc->max_total_qng - 1));
3885 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
3886 (uchar)asc_dvc->max_total_qng);
3887 i++;
3888 s_addr += ASC_QBLK_SIZE;
3889 for (; i <= (uchar)(asc_dvc->max_total_qng + 3);
3890 i++, s_addr += ASC_QBLK_SIZE) {
3891 AscWriteLramByte(iop_base,
3892 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_FWD), i);
3893 AscWriteLramByte(iop_base,
3894 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_BWD), i);
3895 AscWriteLramByte(iop_base,
3896 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_QNO), i);
3897 }
3898}
3899
3900static u32
3901AscLoadMicroCode(PortAddr iop_base, ushort s_addr,
3902 const uchar *mcode_buf, ushort mcode_size)
3903{
3904 u32 chksum;
3905 ushort mcode_word_size;
3906 ushort mcode_chksum;
3907
3908
3909 mcode_word_size = (ushort)(mcode_size >> 1);
3910 AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
3911 AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
3912
3913 chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
3914 ASC_DBG(1, "chksum 0x%lx\n", (ulong)chksum);
3915 mcode_chksum = (ushort)AscMemSumLramWord(iop_base,
3916 (ushort)ASC_CODE_SEC_BEG,
3917 (ushort)((mcode_size -
3918 s_addr - (ushort)
3919 ASC_CODE_SEC_BEG) /
3920 2));
3921 ASC_DBG(1, "mcode_chksum 0x%lx\n", (ulong)mcode_chksum);
3922 AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
3923 AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
3924 return chksum;
3925}
3926
3927static void AscInitQLinkVar(ASC_DVC_VAR *asc_dvc)
3928{
3929 PortAddr iop_base;
3930 int i;
3931 ushort lram_addr;
3932
3933 iop_base = asc_dvc->iop_base;
3934 AscPutRiscVarFreeQHead(iop_base, 1);
3935 AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
3936 AscPutVarFreeQHead(iop_base, 1);
3937 AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
3938 AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
3939 (uchar)((int)asc_dvc->max_total_qng + 1));
3940 AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
3941 (uchar)((int)asc_dvc->max_total_qng + 2));
3942 AscWriteLramByte(iop_base, (ushort)ASCV_TOTAL_READY_Q_B,
3943 asc_dvc->max_total_qng);
3944 AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
3945 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
3946 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
3947 AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
3948 AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
3949 AscPutQDoneInProgress(iop_base, 0);
3950 lram_addr = ASC_QADR_BEG;
3951 for (i = 0; i < 32; i++, lram_addr += 2) {
3952 AscWriteLramWord(iop_base, lram_addr, 0);
3953 }
3954}
3955
3956static int AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
3957{
3958 int i;
3959 int warn_code;
3960 PortAddr iop_base;
3961 __le32 phy_addr;
3962 __le32 phy_size;
3963 struct asc_board *board = asc_dvc_to_board(asc_dvc);
3964
3965 iop_base = asc_dvc->iop_base;
3966 warn_code = 0;
3967 for (i = 0; i <= ASC_MAX_TID; i++) {
3968 AscPutMCodeInitSDTRAtID(iop_base, i,
3969 asc_dvc->cfg->sdtr_period_offset[i]);
3970 }
3971
3972 AscInitQLinkVar(asc_dvc);
3973 AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
3974 asc_dvc->cfg->disc_enable);
3975 AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
3976 ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
3977
3978
3979 BUG_ON((unsigned long)asc_dvc->overrun_buf & 7);
3980 asc_dvc->overrun_dma = dma_map_single(board->dev, asc_dvc->overrun_buf,
3981 ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE);
3982 if (dma_mapping_error(board->dev, asc_dvc->overrun_dma)) {
3983 warn_code = -ENOMEM;
3984 goto err_dma_map;
3985 }
3986 phy_addr = cpu_to_le32(asc_dvc->overrun_dma);
3987 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
3988 (uchar *)&phy_addr, 1);
3989 phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE);
3990 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
3991 (uchar *)&phy_size, 1);
3992
3993 asc_dvc->cfg->mcode_date =
3994 AscReadLramWord(iop_base, (ushort)ASCV_MC_DATE_W);
3995 asc_dvc->cfg->mcode_version =
3996 AscReadLramWord(iop_base, (ushort)ASCV_MC_VER_W);
3997
3998 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
3999 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
4000 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
4001 warn_code = -EINVAL;
4002 goto err_mcode_start;
4003 }
4004 if (AscStartChip(iop_base) != 1) {
4005 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
4006 warn_code = -EIO;
4007 goto err_mcode_start;
4008 }
4009
4010 return warn_code;
4011
4012err_mcode_start:
4013 dma_unmap_single(board->dev, asc_dvc->overrun_dma,
4014 ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE);
4015err_dma_map:
4016 asc_dvc->overrun_dma = 0;
4017 return warn_code;
4018}
4019
4020static int AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
4021{
4022 const struct firmware *fw;
4023 const char fwname[] = "advansys/mcode.bin";
4024 int err;
4025 unsigned long chksum;
4026 int warn_code;
4027 PortAddr iop_base;
4028
4029 iop_base = asc_dvc->iop_base;
4030 warn_code = 0;
4031 if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
4032 !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
4033 AscResetChipAndScsiBus(asc_dvc);
4034 mdelay(asc_dvc->scsi_reset_wait * 1000);
4035 }
4036 asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
4037 if (asc_dvc->err_code != 0)
4038 return ASC_ERROR;
4039 if (!AscFindSignature(asc_dvc->iop_base)) {
4040 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
4041 return warn_code;
4042 }
4043 AscDisableInterrupt(iop_base);
4044 AscInitLram(asc_dvc);
4045
4046 err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev);
4047 if (err) {
4048 printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
4049 fwname, err);
4050 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
4051 return err;
4052 }
4053 if (fw->size < 4) {
4054 printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
4055 fw->size, fwname);
4056 release_firmware(fw);
4057 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
4058 return -EINVAL;
4059 }
4060 chksum = (fw->data[3] << 24) | (fw->data[2] << 16) |
4061 (fw->data[1] << 8) | fw->data[0];
4062 ASC_DBG(1, "_asc_mcode_chksum 0x%lx\n", (ulong)chksum);
4063 if (AscLoadMicroCode(iop_base, 0, &fw->data[4],
4064 fw->size - 4) != chksum) {
4065 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
4066 release_firmware(fw);
4067 return warn_code;
4068 }
4069 release_firmware(fw);
4070 warn_code |= AscInitMicroCodeVar(asc_dvc);
4071 if (!asc_dvc->overrun_dma)
4072 return warn_code;
4073 asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
4074 AscEnableInterrupt(iop_base);
4075 return warn_code;
4076}
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100static int AdvLoadMicrocode(AdvPortAddr iop_base, const unsigned char *buf,
4101 int size, int memsize, int chksum)
4102{
4103 int i, j, end, len = 0;
4104 u32 sum;
4105
4106 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
4107
4108 for (i = 253 * 2; i < size; i++) {
4109 if (buf[i] == 0xff) {
4110 unsigned short word = (buf[i + 3] << 8) | buf[i + 2];
4111 for (j = 0; j < buf[i + 1]; j++) {
4112 AdvWriteWordAutoIncLram(iop_base, word);
4113 len += 2;
4114 }
4115 i += 3;
4116 } else if (buf[i] == 0xfe) {
4117 unsigned short word = (buf[i + 2] << 8) | buf[i + 1];
4118 AdvWriteWordAutoIncLram(iop_base, word);
4119 i += 2;
4120 len += 2;
4121 } else {
4122 unsigned int off = buf[i] * 2;
4123 unsigned short word = (buf[off + 1] << 8) | buf[off];
4124 AdvWriteWordAutoIncLram(iop_base, word);
4125 len += 2;
4126 }
4127 }
4128
4129 end = len;
4130
4131 while (len < memsize) {
4132 AdvWriteWordAutoIncLram(iop_base, 0);
4133 len += 2;
4134 }
4135
4136
4137 sum = 0;
4138 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
4139
4140 for (len = 0; len < end; len += 2) {
4141 sum += AdvReadWordAutoIncLram(iop_base);
4142 }
4143
4144 if (sum != chksum)
4145 return ASC_IERR_MCODE_CHKSUM;
4146
4147 return 0;
4148}
4149
4150static void AdvBuildCarrierFreelist(struct adv_dvc_var *adv_dvc)
4151{
4152 off_t carr_offset = 0, next_offset;
4153 dma_addr_t carr_paddr;
4154 int carr_num = ADV_CARRIER_BUFSIZE / sizeof(ADV_CARR_T), i;
4155
4156 for (i = 0; i < carr_num; i++) {
4157 carr_offset = i * sizeof(ADV_CARR_T);
4158
4159 carr_paddr = adv_dvc->carrier_addr + carr_offset;
4160
4161 adv_dvc->carrier[i].carr_pa = cpu_to_le32(carr_paddr);
4162 adv_dvc->carrier[i].carr_va = cpu_to_le32(carr_offset);
4163 adv_dvc->carrier[i].areq_vpa = 0;
4164 next_offset = carr_offset + sizeof(ADV_CARR_T);
4165 if (i == carr_num)
4166 next_offset = ~0;
4167 adv_dvc->carrier[i].next_vpa = cpu_to_le32(next_offset);
4168 }
4169
4170
4171
4172
4173
4174
4175 adv_dvc->carr_freelist = &adv_dvc->carrier[1];
4176}
4177
4178static ADV_CARR_T *adv_get_carrier(struct adv_dvc_var *adv_dvc, u32 offset)
4179{
4180 int index;
4181
4182 BUG_ON(offset > ADV_CARRIER_BUFSIZE);
4183
4184 index = offset / sizeof(ADV_CARR_T);
4185 return &adv_dvc->carrier[index];
4186}
4187
4188static ADV_CARR_T *adv_get_next_carrier(struct adv_dvc_var *adv_dvc)
4189{
4190 ADV_CARR_T *carrp = adv_dvc->carr_freelist;
4191 u32 next_vpa = le32_to_cpu(carrp->next_vpa);
4192
4193 if (next_vpa == 0 || next_vpa == ~0) {
4194 ASC_DBG(1, "invalid vpa offset 0x%x\n", next_vpa);
4195 return NULL;
4196 }
4197
4198 adv_dvc->carr_freelist = adv_get_carrier(adv_dvc, next_vpa);
4199
4200
4201
4202 carrp->next_vpa = cpu_to_le32(ADV_CQ_STOPPER);
4203
4204 return carrp;
4205}
4206
4207
4208
4209
4210static adv_req_t * adv_get_reqp(struct adv_dvc_var *adv_dvc, u32 offset)
4211{
4212 struct asc_board *boardp = adv_dvc->drv_ptr;
4213
4214 BUG_ON(offset > adv_dvc->max_host_qng);
4215 return &boardp->adv_reqp[offset];
4216}
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232static int
4233AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
4234 ushort idle_cmd, u32 idle_cmd_parameter)
4235{
4236 int result, i, j;
4237 AdvPortAddr iop_base;
4238
4239 iop_base = asc_dvc->iop_base;
4240
4241
4242
4243
4244
4245
4246 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort)0);
4247
4248
4249
4250
4251
4252
4253
4254 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
4255 cpu_to_le32(idle_cmd_parameter));
4256 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
4257
4258
4259
4260
4261 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
4262 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
4263
4264
4265
4266
4267
4268 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
4269 }
4270
4271
4272 for (i = 0; i < SCSI_WAIT_100_MSEC; i++) {
4273
4274 for (j = 0; j < SCSI_US_PER_MSEC; j++) {
4275 AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS,
4276 result);
4277 if (result != 0)
4278 return result;
4279 udelay(1);
4280 }
4281 }
4282
4283 BUG();
4284 return ADV_ERROR;
4285}
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296static int AdvResetSB(ADV_DVC_VAR *asc_dvc)
4297{
4298 int status;
4299
4300
4301
4302
4303
4304 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_START, 0L);
4305 if (status != ADV_TRUE) {
4306 return status;
4307 }
4308
4309
4310
4311
4312
4313
4314
4315 udelay(ASC_SCSI_RESET_HOLD_TIME_US);
4316
4317
4318
4319
4320
4321 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_END, 0L);
4322 if (status != ADV_TRUE) {
4323 return status;
4324 }
4325
4326 mdelay(asc_dvc->scsi_reset_wait * 1000);
4327
4328 return status;
4329}
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
4342{
4343 const struct firmware *fw;
4344 const char fwname[] = "advansys/3550.bin";
4345 AdvPortAddr iop_base;
4346 ushort warn_code;
4347 int begin_addr;
4348 int end_addr;
4349 ushort code_sum;
4350 int word;
4351 int i;
4352 int err;
4353 unsigned long chksum;
4354 ushort scsi_cfg1;
4355 uchar tid;
4356 ushort bios_mem[ASC_MC_BIOSLEN / 2];
4357 ushort wdtr_able = 0, sdtr_able, tagqng_able;
4358 uchar max_cmd[ADV_MAX_TID + 1];
4359
4360
4361 if (asc_dvc->err_code != 0)
4362 return ADV_ERROR;
4363
4364
4365
4366
4367 if (asc_dvc->chip_type != ADV_CHIP_ASC3550) {
4368 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
4369 return ADV_ERROR;
4370 }
4371
4372 warn_code = 0;
4373 iop_base = asc_dvc->iop_base;
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
4384 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
4385 bios_mem[i]);
4386 }
4387
4388
4389
4390
4391 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == 0x55AA) {
4392 ushort bios_version, major, minor;
4393
4394 bios_version =
4395 bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM) / 2];
4396 major = (bios_version >> 12) & 0xF;
4397 minor = (bios_version >> 8) & 0xF;
4398 if (major < 3 || (major == 3 && minor == 1)) {
4399
4400 AdvReadWordLram(iop_base, 0x120, wdtr_able);
4401 } else {
4402 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
4403 }
4404 }
4405 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
4406 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
4407 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
4408 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
4409 max_cmd[tid]);
4410 }
4411
4412 err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev);
4413 if (err) {
4414 printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
4415 fwname, err);
4416 asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM;
4417 return err;
4418 }
4419 if (fw->size < 4) {
4420 printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
4421 fw->size, fwname);
4422 release_firmware(fw);
4423 asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM;
4424 return -EINVAL;
4425 }
4426 chksum = (fw->data[3] << 24) | (fw->data[2] << 16) |
4427 (fw->data[1] << 8) | fw->data[0];
4428 asc_dvc->err_code = AdvLoadMicrocode(iop_base, &fw->data[4],
4429 fw->size - 4, ADV_3550_MEMSIZE,
4430 chksum);
4431 release_firmware(fw);
4432 if (asc_dvc->err_code)
4433 return ADV_ERROR;
4434
4435
4436
4437
4438 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
4439 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
4440 bios_mem[i]);
4441 }
4442
4443
4444
4445
4446
4447 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
4448 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
4449 code_sum = 0;
4450 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
4451 for (word = begin_addr; word < end_addr; word += 2) {
4452 code_sum += AdvReadWordAutoIncLram(iop_base);
4453 }
4454 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
4455
4456
4457
4458
4459 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
4460 asc_dvc->cfg->mcode_date);
4461 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
4462 asc_dvc->cfg->mcode_version);
4463
4464
4465
4466
4467 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
4468
4469
4470
4471
4472
4473
4474
4475 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
4476 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
4477 word |= CONTROL_FLAG_IGNORE_PERR;
4478 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
4479 }
4480
4481
4482
4483
4484
4485 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
4486 START_CTL_EMFU | READ_CMD_MRM);
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
4501 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
4502 asc_dvc->wdtr_able);
4503 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
4504 asc_dvc->sdtr_able);
4505 }
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529 word = 0;
4530 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
4531 if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able) {
4532
4533 word |= (0x3 << (4 * (tid % 4)));
4534 } else {
4535
4536 word |= (0x2 << (4 * (tid % 4)));
4537 }
4538 if (tid == 3) {
4539 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
4540 word = 0;
4541 } else if (tid == 7) {
4542 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
4543 word = 0;
4544 } else if (tid == 11) {
4545 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
4546 word = 0;
4547 } else if (tid == 15) {
4548 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
4549
4550 }
4551 }
4552
4553
4554
4555
4556 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
4557 asc_dvc->cfg->disc_enable);
4558
4559
4560
4561
4562
4563
4564
4565 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
4566 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
4567 asc_dvc->chip_scsi_id);
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
4578
4579
4580
4581
4582 if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
4583 (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) {
4584 asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
4585 return ADV_ERROR;
4586 }
4587
4588
4589
4590
4591
4592
4593 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
4594 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
4595 return ADV_ERROR;
4596 }
4597
4598
4599
4600
4601
4602 if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0) {
4603 asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
4604 return ADV_ERROR;
4605 }
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615 if (asc_dvc->cfg->termination == 0) {
4616
4617
4618
4619
4620 asc_dvc->cfg->termination |= TERM_CTL_SEL;
4621
4622 switch (scsi_cfg1 & CABLE_DETECT) {
4623
4624 case 0x3:
4625 case 0x7:
4626 case 0xB:
4627 case 0xD:
4628 case 0xE:
4629 case 0xF:
4630 asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
4631 break;
4632
4633
4634 case 0x1:
4635 case 0x5:
4636 case 0x9:
4637 case 0xA:
4638 case 0xC:
4639 asc_dvc->cfg->termination |= TERM_CTL_H;
4640 break;
4641
4642
4643 case 0x2:
4644 case 0x6:
4645 break;
4646 }
4647 }
4648
4649
4650
4651
4652 scsi_cfg1 &= ~TERM_CTL;
4653
4654
4655
4656
4657
4658
4659
4660 scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
4672 FLTR_DISABLE | scsi_cfg1);
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
4686 BIOS_EN | RAM_SZ_8KB);
4687
4688
4689
4690
4691
4692
4693
4694 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
4695 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
4696
4697 AdvBuildCarrierFreelist(asc_dvc);
4698
4699
4700
4701
4702
4703 asc_dvc->icq_sp = adv_get_next_carrier(asc_dvc);
4704 if (!asc_dvc->icq_sp) {
4705 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
4706 return ADV_ERROR;
4707 }
4708
4709
4710
4711
4712 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
4713
4714
4715
4716
4717 asc_dvc->irq_sp = adv_get_next_carrier(asc_dvc);
4718 if (!asc_dvc->irq_sp) {
4719 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
4720 return ADV_ERROR;
4721 }
4722
4723
4724
4725
4726 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
4727 asc_dvc->carr_pending_cnt = 0;
4728
4729 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
4730 (ADV_INTR_ENABLE_HOST_INTR |
4731 ADV_INTR_ENABLE_GLOBAL_INTR));
4732
4733 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
4734 AdvWriteWordRegister(iop_base, IOPW_PC, word);
4735
4736
4737 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
4738
4739
4740
4741
4742
4743
4744 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
4745
4746
4747
4748
4749
4750 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
4751 0x55AA) {
4752
4753
4754
4755 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
4756 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
4757 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
4758 tagqng_able);
4759 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
4760 AdvWriteByteLram(iop_base,
4761 ASC_MC_NUMBER_OF_MAX_CMD + tid,
4762 max_cmd[tid]);
4763 }
4764 } else {
4765 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
4766 warn_code = ASC_WARN_BUSRESET_ERROR;
4767 }
4768 }
4769 }
4770
4771 return warn_code;
4772}
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
4785{
4786 const struct firmware *fw;
4787 const char fwname[] = "advansys/38C0800.bin";
4788 AdvPortAddr iop_base;
4789 ushort warn_code;
4790 int begin_addr;
4791 int end_addr;
4792 ushort code_sum;
4793 int word;
4794 int i;
4795 int err;
4796 unsigned long chksum;
4797 ushort scsi_cfg1;
4798 uchar byte;
4799 uchar tid;
4800 ushort bios_mem[ASC_MC_BIOSLEN / 2];
4801 ushort wdtr_able, sdtr_able, tagqng_able;
4802 uchar max_cmd[ADV_MAX_TID + 1];
4803
4804
4805 if (asc_dvc->err_code != 0)
4806 return ADV_ERROR;
4807
4808
4809
4810
4811 if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800) {
4812 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
4813 return ADV_ERROR;
4814 }
4815
4816 warn_code = 0;
4817 iop_base = asc_dvc->iop_base;
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
4828 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
4829 bios_mem[i]);
4830 }
4831
4832
4833
4834
4835 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
4836 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
4837 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
4838 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
4839 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
4840 max_cmd[tid]);
4841 }
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872 for (i = 0; i < 2; i++) {
4873 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
4874 mdelay(10);
4875 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
4876 if ((byte & RAM_TEST_DONE) == 0
4877 || (byte & 0x0F) != PRE_TEST_VALUE) {
4878 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
4879 return ADV_ERROR;
4880 }
4881
4882 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
4883 mdelay(10);
4884 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
4885 != NORMAL_VALUE) {
4886 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
4887 return ADV_ERROR;
4888 }
4889 }
4890
4891
4892
4893
4894
4895
4896
4897
4898 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
4899 mdelay(10);
4900
4901 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
4902 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
4903
4904 asc_dvc->bist_err_code = byte;
4905 asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST;
4906 return ADV_ERROR;
4907 }
4908
4909
4910 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
4911
4912 err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev);
4913 if (err) {
4914 printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
4915 fwname, err);
4916 asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM;
4917 return err;
4918 }
4919 if (fw->size < 4) {
4920 printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
4921 fw->size, fwname);
4922 release_firmware(fw);
4923 asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM;
4924 return -EINVAL;
4925 }
4926 chksum = (fw->data[3] << 24) | (fw->data[2] << 16) |
4927 (fw->data[1] << 8) | fw->data[0];
4928 asc_dvc->err_code = AdvLoadMicrocode(iop_base, &fw->data[4],
4929 fw->size - 4, ADV_38C0800_MEMSIZE,
4930 chksum);
4931 release_firmware(fw);
4932 if (asc_dvc->err_code)
4933 return ADV_ERROR;
4934
4935
4936
4937
4938 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
4939 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
4940 bios_mem[i]);
4941 }
4942
4943
4944
4945
4946
4947 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
4948 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
4949 code_sum = 0;
4950 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
4951 for (word = begin_addr; word < end_addr; word += 2) {
4952 code_sum += AdvReadWordAutoIncLram(iop_base);
4953 }
4954 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
4955
4956
4957
4958
4959 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
4960 asc_dvc->cfg->mcode_date);
4961 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
4962 asc_dvc->cfg->mcode_version);
4963
4964
4965
4966
4967 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
4978 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
4979 scsi_cfg1 | DIS_TERM_DRV);
4980
4981
4982
4983
4984
4985
4986
4987 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
4988 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
4989 word |= CONTROL_FLAG_IGNORE_PERR;
4990 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
4991 }
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
5002 BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH |
5003 READ_CMD_MRM);
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
5018 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
5019 asc_dvc->wdtr_able);
5020 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
5021 asc_dvc->sdtr_able);
5022 }
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
5034 asc_dvc->cfg->disc_enable);
5035 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
5036 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
5037 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
5038 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
5039
5040
5041
5042
5043
5044
5045
5046 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
5047 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
5048 asc_dvc->chip_scsi_id);
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
5059
5060
5061
5062
5063
5064
5065 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
5066 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
5067 return ADV_ERROR;
5068 }
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081 if (scsi_cfg1 & HVD) {
5082 asc_dvc->err_code = ASC_IERR_HVD_DEVICE;
5083 return ADV_ERROR;
5084 }
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
5095
5096 switch (scsi_cfg1 & C_DET_SE) {
5097
5098 case 0x1:
5099 case 0x2:
5100 case 0x3:
5101 asc_dvc->cfg->termination |= TERM_SE;
5102 break;
5103
5104
5105 case 0x0:
5106 asc_dvc->cfg->termination |= TERM_SE_HI;
5107 break;
5108 }
5109 }
5110
5111 if ((asc_dvc->cfg->termination & TERM_LVD) == 0) {
5112
5113 switch (scsi_cfg1 & C_DET_LVD) {
5114
5115 case 0x4:
5116 case 0x8:
5117 case 0xC:
5118 asc_dvc->cfg->termination |= TERM_LVD;
5119 break;
5120
5121
5122 case 0x0:
5123 break;
5124 }
5125 }
5126
5127
5128
5129
5130 scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
5131
5132
5133
5134
5135 scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
5136
5137
5138
5139
5140
5141
5142 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
5167 BIOS_EN | RAM_SZ_16KB);
5168
5169
5170
5171
5172
5173
5174
5175 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
5176 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
5177
5178 AdvBuildCarrierFreelist(asc_dvc);
5179
5180
5181
5182
5183
5184 asc_dvc->icq_sp = adv_get_next_carrier(asc_dvc);
5185 if (!asc_dvc->icq_sp) {
5186 ASC_DBG(0, "Failed to get ICQ carrier\n");
5187 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
5188 return ADV_ERROR;
5189 }
5190
5191
5192
5193
5194
5195 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
5196
5197
5198
5199
5200 asc_dvc->irq_sp = adv_get_next_carrier(asc_dvc);
5201 if (!asc_dvc->irq_sp) {
5202 ASC_DBG(0, "Failed to get IRQ carrier\n");
5203 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
5204 return ADV_ERROR;
5205 }
5206
5207
5208
5209
5210
5211
5212 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
5213 asc_dvc->carr_pending_cnt = 0;
5214
5215 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
5216 (ADV_INTR_ENABLE_HOST_INTR |
5217 ADV_INTR_ENABLE_GLOBAL_INTR));
5218
5219 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
5220 AdvWriteWordRegister(iop_base, IOPW_PC, word);
5221
5222
5223 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
5224
5225
5226
5227
5228
5229
5230 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
5231
5232
5233
5234
5235
5236 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
5237 0x55AA) {
5238
5239
5240
5241 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
5242 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
5243 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
5244 tagqng_able);
5245 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
5246 AdvWriteByteLram(iop_base,
5247 ASC_MC_NUMBER_OF_MAX_CMD + tid,
5248 max_cmd[tid]);
5249 }
5250 } else {
5251 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
5252 warn_code = ASC_WARN_BUSRESET_ERROR;
5253 }
5254 }
5255 }
5256
5257 return warn_code;
5258}
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
5271{
5272 const struct firmware *fw;
5273 const char fwname[] = "advansys/38C1600.bin";
5274 AdvPortAddr iop_base;
5275 ushort warn_code;
5276 int begin_addr;
5277 int end_addr;
5278 ushort code_sum;
5279 long word;
5280 int i;
5281 int err;
5282 unsigned long chksum;
5283 ushort scsi_cfg1;
5284 uchar byte;
5285 uchar tid;
5286 ushort bios_mem[ASC_MC_BIOSLEN / 2];
5287 ushort wdtr_able, sdtr_able, ppr_able, tagqng_able;
5288 uchar max_cmd[ASC_MAX_TID + 1];
5289
5290
5291 if (asc_dvc->err_code != 0) {
5292 return ADV_ERROR;
5293 }
5294
5295
5296
5297
5298 if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
5299 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
5300 return ADV_ERROR;
5301 }
5302
5303 warn_code = 0;
5304 iop_base = asc_dvc->iop_base;
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
5315 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
5316 bios_mem[i]);
5317 }
5318
5319
5320
5321
5322 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
5323 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
5324 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
5325 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
5326 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
5327 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
5328 max_cmd[tid]);
5329 }
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360 for (i = 0; i < 2; i++) {
5361 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
5362 mdelay(10);
5363 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
5364 if ((byte & RAM_TEST_DONE) == 0
5365 || (byte & 0x0F) != PRE_TEST_VALUE) {
5366 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
5367 return ADV_ERROR;
5368 }
5369
5370 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
5371 mdelay(10);
5372 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
5373 != NORMAL_VALUE) {
5374 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
5375 return ADV_ERROR;
5376 }
5377 }
5378
5379
5380
5381
5382
5383
5384
5385
5386 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
5387 mdelay(10);
5388
5389 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
5390 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
5391
5392 asc_dvc->bist_err_code = byte;
5393 asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST;
5394 return ADV_ERROR;
5395 }
5396
5397
5398 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
5399
5400 err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev);
5401 if (err) {
5402 printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
5403 fwname, err);
5404 asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM;
5405 return err;
5406 }
5407 if (fw->size < 4) {
5408 printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
5409 fw->size, fwname);
5410 release_firmware(fw);
5411 asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM;
5412 return -EINVAL;
5413 }
5414 chksum = (fw->data[3] << 24) | (fw->data[2] << 16) |
5415 (fw->data[1] << 8) | fw->data[0];
5416 asc_dvc->err_code = AdvLoadMicrocode(iop_base, &fw->data[4],
5417 fw->size - 4, ADV_38C1600_MEMSIZE,
5418 chksum);
5419 release_firmware(fw);
5420 if (asc_dvc->err_code)
5421 return ADV_ERROR;
5422
5423
5424
5425
5426 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
5427 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
5428 bios_mem[i]);
5429 }
5430
5431
5432
5433
5434
5435 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
5436 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
5437 code_sum = 0;
5438 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
5439 for (word = begin_addr; word < end_addr; word += 2) {
5440 code_sum += AdvReadWordAutoIncLram(iop_base);
5441 }
5442 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
5443
5444
5445
5446
5447 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
5448 asc_dvc->cfg->mcode_date);
5449 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
5450 asc_dvc->cfg->mcode_version);
5451
5452
5453
5454
5455 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
5466 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
5467 scsi_cfg1 | DIS_TERM_DRV);
5468
5469
5470
5471
5472
5473
5474
5475 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
5476 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
5477 word |= CONTROL_FLAG_IGNORE_PERR;
5478 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
5479 }
5480
5481
5482
5483
5484
5485
5486
5487 if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0) {
5488 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
5489 word |= CONTROL_FLAG_ENABLE_AIPP;
5490 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
5491 }
5492
5493
5494
5495
5496
5497 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
5498 FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
5513 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
5514 asc_dvc->wdtr_able);
5515 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
5516 asc_dvc->sdtr_able);
5517 }
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
5529 asc_dvc->cfg->disc_enable);
5530 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
5531 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
5532 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
5533 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
5534
5535
5536
5537
5538
5539
5540
5541 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
5542 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
5543 asc_dvc->chip_scsi_id);
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
5555
5556
5557
5558
5559
5560
5561 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
5562 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
5563 return ADV_ERROR;
5564 }
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574 if (scsi_cfg1 & HVD) {
5575 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
5576 return ADV_ERROR;
5577 }
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
5593 struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc);
5594
5595 switch (scsi_cfg1 & C_DET_SE) {
5596
5597 case 0x1:
5598 case 0x2:
5599 case 0x3:
5600 asc_dvc->cfg->termination |= TERM_SE;
5601 break;
5602
5603 case 0x0:
5604 if (PCI_FUNC(pdev->devfn) == 0) {
5605
5606 } else {
5607
5608 asc_dvc->cfg->termination |= TERM_SE_HI;
5609 }
5610 break;
5611 }
5612 }
5613
5614
5615
5616
5617 scsi_cfg1 &= ~TERM_SE;
5618
5619
5620
5621
5622 scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
5623
5624
5625
5626
5627
5628
5629
5630
5631 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
5664 BIOS_EN | RAM_SZ_16KB);
5665
5666
5667
5668
5669
5670
5671
5672 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
5673 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
5674
5675 AdvBuildCarrierFreelist(asc_dvc);
5676
5677
5678
5679
5680 asc_dvc->icq_sp = adv_get_next_carrier(asc_dvc);
5681 if (!asc_dvc->icq_sp) {
5682 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
5683 return ADV_ERROR;
5684 }
5685
5686
5687
5688
5689
5690
5691 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
5692 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
5693 le32_to_cpu(asc_dvc->icq_sp->carr_pa));
5694
5695
5696
5697
5698 asc_dvc->irq_sp = adv_get_next_carrier(asc_dvc);
5699 if (!asc_dvc->irq_sp) {
5700 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
5701 return ADV_ERROR;
5702 }
5703
5704
5705
5706
5707 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
5708 asc_dvc->carr_pending_cnt = 0;
5709
5710 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
5711 (ADV_INTR_ENABLE_HOST_INTR |
5712 ADV_INTR_ENABLE_GLOBAL_INTR));
5713 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
5714 AdvWriteWordRegister(iop_base, IOPW_PC, word);
5715
5716
5717 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
5718
5719
5720
5721
5722
5723
5724 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
5725
5726
5727
5728
5729 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
5730 0x55AA) {
5731
5732
5733
5734 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
5735 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
5736 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
5737 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
5738 tagqng_able);
5739 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
5740 AdvWriteByteLram(iop_base,
5741 ASC_MC_NUMBER_OF_MAX_CMD + tid,
5742 max_cmd[tid]);
5743 }
5744 } else {
5745 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
5746 warn_code = ASC_WARN_BUSRESET_ERROR;
5747 }
5748 }
5749 }
5750
5751 return warn_code;
5752}
5753
5754
5755
5756
5757
5758
5759
5760
5761static int AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
5762{
5763 int status;
5764 ushort wdtr_able, sdtr_able, tagqng_able;
5765 ushort ppr_able = 0;
5766 uchar tid, max_cmd[ADV_MAX_TID + 1];
5767 AdvPortAddr iop_base;
5768 ushort bios_sig;
5769
5770 iop_base = asc_dvc->iop_base;
5771
5772
5773
5774
5775 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
5776 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
5777 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
5778 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
5779 }
5780 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
5781 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
5782 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
5783 max_cmd[tid]);
5784 }
5785
5786
5787
5788
5789
5790
5791
5792 AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
5793 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
5794
5795
5796
5797
5798 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
5799 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
5800 mdelay(100);
5801 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
5802 ADV_CTRL_REG_CMD_WR_IO_REG);
5803
5804
5805
5806
5807
5808 asc_dvc->err_code = 0;
5809 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
5810 status = AdvInitAsc38C1600Driver(asc_dvc);
5811 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
5812 status = AdvInitAsc38C0800Driver(asc_dvc);
5813 } else {
5814 status = AdvInitAsc3550Driver(asc_dvc);
5815 }
5816
5817
5818 if (status == 0) {
5819 status = ADV_TRUE;
5820 } else {
5821 status = ADV_FALSE;
5822 }
5823
5824
5825
5826
5827 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
5828
5829
5830
5831
5832 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
5833 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
5834 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
5835 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
5836 }
5837 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
5838 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
5839 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
5840 max_cmd[tid]);
5841 }
5842
5843 return status;
5844}
5845
5846
5847
5848
5849static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
5850{
5851 switch (code) {
5852 case ADV_ASYNC_SCSI_BUS_RESET_DET:
5853
5854
5855
5856 ASC_DBG(0, "ADV_ASYNC_SCSI_BUS_RESET_DET\n");
5857 break;
5858
5859 case ADV_ASYNC_RDMA_FAILURE:
5860
5861
5862
5863
5864
5865 ASC_DBG(0, "ADV_ASYNC_RDMA_FAILURE\n");
5866 AdvResetChipAndSB(adv_dvc_varp);
5867 break;
5868
5869 case ADV_HOST_SCSI_BUS_RESET:
5870
5871
5872
5873 ASC_DBG(0, "ADV_HOST_SCSI_BUS_RESET\n");
5874 break;
5875
5876 default:
5877 ASC_DBG(0, "unknown code 0x%x\n", code);
5878 break;
5879 }
5880}
5881
5882
5883
5884
5885
5886
5887static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
5888{
5889 struct asc_board *boardp = adv_dvc_varp->drv_ptr;
5890 adv_req_t *reqp;
5891 adv_sgblk_t *sgblkp;
5892 struct scsi_cmnd *scp;
5893 u32 resid_cnt;
5894 dma_addr_t sense_addr;
5895
5896 ASC_DBG(1, "adv_dvc_varp 0x%p, scsiqp 0x%p\n",
5897 adv_dvc_varp, scsiqp);
5898 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
5899
5900
5901
5902
5903
5904
5905 scp = scsi_host_find_tag(boardp->shost, scsiqp->srb_tag);
5906
5907 ASC_DBG(1, "scp 0x%p\n", scp);
5908 if (scp == NULL) {
5909 ASC_PRINT
5910 ("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
5911 return;
5912 }
5913 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
5914
5915 reqp = (adv_req_t *)scp->host_scribble;
5916 ASC_DBG(1, "reqp 0x%lx\n", (ulong)reqp);
5917 if (reqp == NULL) {
5918 ASC_PRINT("adv_isr_callback: reqp is NULL\n");
5919 return;
5920 }
5921
5922
5923
5924
5925 scp->host_scribble = NULL;
5926 reqp->cmndp = NULL;
5927
5928 ASC_STATS(boardp->shost, callback);
5929 ASC_DBG(1, "shost 0x%p\n", boardp->shost);
5930
5931 sense_addr = le32_to_cpu(scsiqp->sense_addr);
5932 dma_unmap_single(boardp->dev, sense_addr,
5933 SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
5934
5935
5936
5937
5938 scp->result = 0;
5939 switch (scsiqp->done_status) {
5940 case QD_NO_ERROR:
5941 ASC_DBG(2, "QD_NO_ERROR\n");
5942
5943
5944
5945
5946
5947
5948
5949 resid_cnt = le32_to_cpu(scsiqp->data_cnt);
5950 if (scsi_bufflen(scp) != 0 && resid_cnt != 0 &&
5951 resid_cnt <= scsi_bufflen(scp)) {
5952 ASC_DBG(1, "underrun condition %lu bytes\n",
5953 (ulong)resid_cnt);
5954 scsi_set_resid(scp, resid_cnt);
5955 }
5956 break;
5957
5958 case QD_WITH_ERROR:
5959 ASC_DBG(2, "QD_WITH_ERROR\n");
5960 switch (scsiqp->host_status) {
5961 case QHSTA_NO_ERROR:
5962 set_status_byte(scp, scsiqp->scsi_status);
5963 if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
5964 ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n");
5965 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
5966 SCSI_SENSE_BUFFERSIZE);
5967 }
5968 break;
5969
5970 default:
5971
5972 ASC_DBG(1, "host_status 0x%x\n", scsiqp->host_status);
5973 set_host_byte(scp, DID_BAD_TARGET);
5974 break;
5975 }
5976 break;
5977
5978 case QD_ABORTED_BY_HOST:
5979 ASC_DBG(1, "QD_ABORTED_BY_HOST\n");
5980 set_status_byte(scp, scsiqp->scsi_status);
5981 set_host_byte(scp, DID_ABORT);
5982 break;
5983
5984 default:
5985 ASC_DBG(1, "done_status 0x%x\n", scsiqp->done_status);
5986 set_status_byte(scp, scsiqp->scsi_status);
5987 set_host_byte(scp, DID_ERROR);
5988 break;
5989 }
5990
5991
5992
5993
5994
5995
5996 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
5997 scsiqp->done_status == QD_NO_ERROR &&
5998 scsiqp->host_status == QHSTA_NO_ERROR) {
5999 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
6000 }
6001
6002 asc_scsi_done(scp);
6003
6004
6005
6006
6007 while ((sgblkp = reqp->sgblkp) != NULL) {
6008
6009 reqp->sgblkp = sgblkp->next_sgblkp;
6010
6011 dma_pool_free(boardp->adv_sgblk_pool, sgblkp,
6012 sgblkp->sg_addr);
6013 }
6014
6015 ASC_DBG(1, "done\n");
6016}
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037static int AdvISR(ADV_DVC_VAR *asc_dvc)
6038{
6039 AdvPortAddr iop_base;
6040 uchar int_stat;
6041 ADV_CARR_T *free_carrp;
6042 __le32 irq_next_vpa;
6043 ADV_SCSI_REQ_Q *scsiq;
6044 adv_req_t *reqp;
6045
6046 iop_base = asc_dvc->iop_base;
6047
6048
6049 int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
6050
6051 if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
6052 ADV_INTR_STATUS_INTRC)) == 0) {
6053 return ADV_FALSE;
6054 }
6055
6056
6057
6058
6059
6060
6061 if (int_stat & ADV_INTR_STATUS_INTRB) {
6062 uchar intrb_code;
6063
6064 AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
6065
6066 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
6067 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
6068 if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
6069 asc_dvc->carr_pending_cnt != 0) {
6070 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
6071 ADV_TICKLE_A);
6072 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
6073 AdvWriteByteRegister(iop_base,
6074 IOPB_TICKLE,
6075 ADV_TICKLE_NOP);
6076 }
6077 }
6078 }
6079
6080 adv_async_callback(asc_dvc, intrb_code);
6081 }
6082
6083
6084
6085
6086 while (((irq_next_vpa =
6087 le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ADV_RQ_DONE) != 0) {
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097 u32 pa_offset = le32_to_cpu(asc_dvc->irq_sp->areq_vpa);
6098 ASC_DBG(1, "irq_sp %p areq_vpa %u\n",
6099 asc_dvc->irq_sp, pa_offset);
6100 reqp = adv_get_reqp(asc_dvc, pa_offset);
6101 scsiq = &reqp->scsi_req_q;
6102
6103
6104
6105
6106
6107
6108 if ((irq_next_vpa & ADV_RQ_GOOD) != 0) {
6109 scsiq->done_status = QD_NO_ERROR;
6110 scsiq->host_status = scsiq->scsi_status = 0;
6111 scsiq->data_cnt = 0L;
6112 }
6113
6114
6115
6116
6117
6118
6119 free_carrp = asc_dvc->irq_sp;
6120 asc_dvc->irq_sp = adv_get_carrier(asc_dvc,
6121 ADV_GET_CARRP(irq_next_vpa));
6122
6123 free_carrp->next_vpa = asc_dvc->carr_freelist->carr_va;
6124 asc_dvc->carr_freelist = free_carrp;
6125 asc_dvc->carr_pending_cnt--;
6126
6127
6128
6129
6130 scsiq->cntl = 0;
6131
6132
6133
6134
6135
6136 adv_isr_callback(asc_dvc, scsiq);
6137
6138
6139
6140
6141
6142
6143
6144 }
6145 return ADV_TRUE;
6146}
6147
6148static int AscSetLibErrorCode(ASC_DVC_VAR *asc_dvc, ushort err_code)
6149{
6150 if (asc_dvc->err_code == 0) {
6151 asc_dvc->err_code = err_code;
6152 AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
6153 err_code);
6154 }
6155 return err_code;
6156}
6157
6158static void AscAckInterrupt(PortAddr iop_base)
6159{
6160 uchar host_flag;
6161 uchar risc_flag;
6162 ushort loop;
6163
6164 loop = 0;
6165 do {
6166 risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
6167 if (loop++ > 0x7FFF) {
6168 break;
6169 }
6170 } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
6171 host_flag =
6172 AscReadLramByte(iop_base,
6173 ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
6174 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
6175 (uchar)(host_flag | ASC_HOST_FLAG_ACK_INT));
6176 AscSetChipStatus(iop_base, CIW_INT_ACK);
6177 loop = 0;
6178 while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
6179 AscSetChipStatus(iop_base, CIW_INT_ACK);
6180 if (loop++ > 3) {
6181 break;
6182 }
6183 }
6184 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
6185}
6186
6187static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time)
6188{
6189 const uchar *period_table;
6190 int max_index;
6191 int min_index;
6192 int i;
6193
6194 period_table = asc_dvc->sdtr_period_tbl;
6195 max_index = (int)asc_dvc->max_sdtr_index;
6196 min_index = (int)asc_dvc->min_sdtr_index;
6197 if ((syn_time <= period_table[max_index])) {
6198 for (i = min_index; i < (max_index - 1); i++) {
6199 if (syn_time <= period_table[i]) {
6200 return (uchar)i;
6201 }
6202 }
6203 return (uchar)max_index;
6204 } else {
6205 return (uchar)(max_index + 1);
6206 }
6207}
6208
6209static uchar
6210AscMsgOutSDTR(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar sdtr_offset)
6211{
6212 PortAddr iop_base = asc_dvc->iop_base;
6213 uchar sdtr_period_index = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
6214 EXT_MSG sdtr_buf = {
6215 .msg_type = EXTENDED_MESSAGE,
6216 .msg_len = MS_SDTR_LEN,
6217 .msg_req = EXTENDED_SDTR,
6218 .xfer_period = sdtr_period,
6219 .req_ack_offset = sdtr_offset,
6220 };
6221 sdtr_offset &= ASC_SYN_MAX_OFFSET;
6222
6223 if (sdtr_period_index <= asc_dvc->max_sdtr_index) {
6224 AscMemWordCopyPtrToLram(iop_base, ASCV_MSGOUT_BEG,
6225 (uchar *)&sdtr_buf,
6226 sizeof(EXT_MSG) >> 1);
6227 return ((sdtr_period_index << 4) | sdtr_offset);
6228 } else {
6229 sdtr_buf.req_ack_offset = 0;
6230 AscMemWordCopyPtrToLram(iop_base, ASCV_MSGOUT_BEG,
6231 (uchar *)&sdtr_buf,
6232 sizeof(EXT_MSG) >> 1);
6233 return 0;
6234 }
6235}
6236
6237static uchar
6238AscCalSDTRData(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar syn_offset)
6239{
6240 uchar byte;
6241 uchar sdtr_period_ix;
6242
6243 sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
6244 if (sdtr_period_ix > asc_dvc->max_sdtr_index)
6245 return 0xFF;
6246 byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
6247 return byte;
6248}
6249
6250static bool AscSetChipSynRegAtID(PortAddr iop_base, uchar id, uchar sdtr_data)
6251{
6252 ASC_SCSI_BIT_ID_TYPE org_id;
6253 int i;
6254 bool sta = true;
6255
6256 AscSetBank(iop_base, 1);
6257 org_id = AscReadChipDvcID(iop_base);
6258 for (i = 0; i <= ASC_MAX_TID; i++) {
6259 if (org_id == (0x01 << i))
6260 break;
6261 }
6262 org_id = (ASC_SCSI_BIT_ID_TYPE) i;
6263 AscWriteChipDvcID(iop_base, id);
6264 if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
6265 AscSetBank(iop_base, 0);
6266 AscSetChipSyn(iop_base, sdtr_data);
6267 if (AscGetChipSyn(iop_base) != sdtr_data) {
6268 sta = false;
6269 }
6270 } else {
6271 sta = false;
6272 }
6273 AscSetBank(iop_base, 1);
6274 AscWriteChipDvcID(iop_base, org_id);
6275 AscSetBank(iop_base, 0);
6276 return (sta);
6277}
6278
6279static void AscSetChipSDTR(PortAddr iop_base, uchar sdtr_data, uchar tid_no)
6280{
6281 AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
6282 AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
6283}
6284
6285static void AscIsrChipHalted(ASC_DVC_VAR *asc_dvc)
6286{
6287 EXT_MSG ext_msg;
6288 EXT_MSG out_msg;
6289 ushort halt_q_addr;
6290 bool sdtr_accept;
6291 ushort int_halt_code;
6292 ASC_SCSI_BIT_ID_TYPE scsi_busy;
6293 ASC_SCSI_BIT_ID_TYPE target_id;
6294 PortAddr iop_base;
6295 uchar tag_code;
6296 uchar q_status;
6297 uchar halt_qp;
6298 uchar sdtr_data;
6299 uchar target_ix;
6300 uchar q_cntl, tid_no;
6301 uchar cur_dvc_qng;
6302 uchar asyn_sdtr;
6303 uchar scsi_status;
6304 struct asc_board *boardp;
6305
6306 BUG_ON(!asc_dvc->drv_ptr);
6307 boardp = asc_dvc->drv_ptr;
6308
6309 iop_base = asc_dvc->iop_base;
6310 int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
6311
6312 halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
6313 halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
6314 target_ix = AscReadLramByte(iop_base,
6315 (ushort)(halt_q_addr +
6316 (ushort)ASC_SCSIQ_B_TARGET_IX));
6317 q_cntl = AscReadLramByte(iop_base,
6318 (ushort)(halt_q_addr + (ushort)ASC_SCSIQ_B_CNTL));
6319 tid_no = ASC_TIX_TO_TID(target_ix);
6320 target_id = (uchar)ASC_TID_TO_TARGET_ID(tid_no);
6321 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
6322 asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
6323 } else {
6324 asyn_sdtr = 0;
6325 }
6326 if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
6327 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
6328 AscSetChipSDTR(iop_base, 0, tid_no);
6329 boardp->sdtr_data[tid_no] = 0;
6330 }
6331 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6332 return;
6333 } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
6334 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
6335 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
6336 boardp->sdtr_data[tid_no] = asyn_sdtr;
6337 }
6338 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6339 return;
6340 } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
6341 AscMemWordCopyPtrFromLram(iop_base,
6342 ASCV_MSGIN_BEG,
6343 (uchar *)&ext_msg,
6344 sizeof(EXT_MSG) >> 1);
6345
6346 if (ext_msg.msg_type == EXTENDED_MESSAGE &&
6347 ext_msg.msg_req == EXTENDED_SDTR &&
6348 ext_msg.msg_len == MS_SDTR_LEN) {
6349 sdtr_accept = true;
6350 if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
6351
6352 sdtr_accept = false;
6353 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
6354 }
6355 if ((ext_msg.xfer_period <
6356 asc_dvc->sdtr_period_tbl[asc_dvc->min_sdtr_index])
6357 || (ext_msg.xfer_period >
6358 asc_dvc->sdtr_period_tbl[asc_dvc->
6359 max_sdtr_index])) {
6360 sdtr_accept = false;
6361 ext_msg.xfer_period =
6362 asc_dvc->sdtr_period_tbl[asc_dvc->
6363 min_sdtr_index];
6364 }
6365 if (sdtr_accept) {
6366 sdtr_data =
6367 AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
6368 ext_msg.req_ack_offset);
6369 if (sdtr_data == 0xFF) {
6370
6371 q_cntl |= QC_MSG_OUT;
6372 asc_dvc->init_sdtr &= ~target_id;
6373 asc_dvc->sdtr_done &= ~target_id;
6374 AscSetChipSDTR(iop_base, asyn_sdtr,
6375 tid_no);
6376 boardp->sdtr_data[tid_no] = asyn_sdtr;
6377 }
6378 }
6379 if (ext_msg.req_ack_offset == 0) {
6380
6381 q_cntl &= ~QC_MSG_OUT;
6382 asc_dvc->init_sdtr &= ~target_id;
6383 asc_dvc->sdtr_done &= ~target_id;
6384 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
6385 } else {
6386 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
6387 q_cntl &= ~QC_MSG_OUT;
6388 asc_dvc->sdtr_done |= target_id;
6389 asc_dvc->init_sdtr |= target_id;
6390 asc_dvc->pci_fix_asyn_xfer &=
6391 ~target_id;
6392 sdtr_data =
6393 AscCalSDTRData(asc_dvc,
6394 ext_msg.xfer_period,
6395 ext_msg.
6396 req_ack_offset);
6397 AscSetChipSDTR(iop_base, sdtr_data,
6398 tid_no);
6399 boardp->sdtr_data[tid_no] = sdtr_data;
6400 } else {
6401 q_cntl |= QC_MSG_OUT;
6402 AscMsgOutSDTR(asc_dvc,
6403 ext_msg.xfer_period,
6404 ext_msg.req_ack_offset);
6405 asc_dvc->pci_fix_asyn_xfer &=
6406 ~target_id;
6407 sdtr_data =
6408 AscCalSDTRData(asc_dvc,
6409 ext_msg.xfer_period,
6410 ext_msg.
6411 req_ack_offset);
6412 AscSetChipSDTR(iop_base, sdtr_data,
6413 tid_no);
6414 boardp->sdtr_data[tid_no] = sdtr_data;
6415 asc_dvc->sdtr_done |= target_id;
6416 asc_dvc->init_sdtr |= target_id;
6417 }
6418 }
6419
6420 AscWriteLramByte(iop_base,
6421 (ushort)(halt_q_addr +
6422 (ushort)ASC_SCSIQ_B_CNTL),
6423 q_cntl);
6424 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6425 return;
6426 } else if (ext_msg.msg_type == EXTENDED_MESSAGE &&
6427 ext_msg.msg_req == EXTENDED_WDTR &&
6428 ext_msg.msg_len == MS_WDTR_LEN) {
6429
6430 ext_msg.wdtr_width = 0;
6431 AscMemWordCopyPtrToLram(iop_base,
6432 ASCV_MSGOUT_BEG,
6433 (uchar *)&ext_msg,
6434 sizeof(EXT_MSG) >> 1);
6435 q_cntl |= QC_MSG_OUT;
6436 AscWriteLramByte(iop_base,
6437 (ushort)(halt_q_addr +
6438 (ushort)ASC_SCSIQ_B_CNTL),
6439 q_cntl);
6440 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6441 return;
6442 } else {
6443
6444 ext_msg.msg_type = MESSAGE_REJECT;
6445 AscMemWordCopyPtrToLram(iop_base,
6446 ASCV_MSGOUT_BEG,
6447 (uchar *)&ext_msg,
6448 sizeof(EXT_MSG) >> 1);
6449 q_cntl |= QC_MSG_OUT;
6450 AscWriteLramByte(iop_base,
6451 (ushort)(halt_q_addr +
6452 (ushort)ASC_SCSIQ_B_CNTL),
6453 q_cntl);
6454 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6455 return;
6456 }
6457 } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
6458
6459 q_cntl |= QC_REQ_SENSE;
6460
6461 if ((asc_dvc->init_sdtr & target_id) != 0) {
6462
6463 asc_dvc->sdtr_done &= ~target_id;
6464
6465 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
6466 q_cntl |= QC_MSG_OUT;
6467 AscMsgOutSDTR(asc_dvc,
6468 asc_dvc->
6469 sdtr_period_tbl[(sdtr_data >> 4) &
6470 (uchar)(asc_dvc->
6471 max_sdtr_index -
6472 1)],
6473 (uchar)(sdtr_data & (uchar)
6474 ASC_SYN_MAX_OFFSET));
6475 }
6476
6477 AscWriteLramByte(iop_base,
6478 (ushort)(halt_q_addr +
6479 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
6480
6481 tag_code = AscReadLramByte(iop_base,
6482 (ushort)(halt_q_addr + (ushort)
6483 ASC_SCSIQ_B_TAG_CODE));
6484 tag_code &= 0xDC;
6485 if ((asc_dvc->pci_fix_asyn_xfer & target_id)
6486 && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
6487 ) {
6488
6489 tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
6490 | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
6491
6492 }
6493 AscWriteLramByte(iop_base,
6494 (ushort)(halt_q_addr +
6495 (ushort)ASC_SCSIQ_B_TAG_CODE),
6496 tag_code);
6497
6498 q_status = AscReadLramByte(iop_base,
6499 (ushort)(halt_q_addr + (ushort)
6500 ASC_SCSIQ_B_STATUS));
6501 q_status |= (QS_READY | QS_BUSY);
6502 AscWriteLramByte(iop_base,
6503 (ushort)(halt_q_addr +
6504 (ushort)ASC_SCSIQ_B_STATUS),
6505 q_status);
6506
6507 scsi_busy = AscReadLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B);
6508 scsi_busy &= ~target_id;
6509 AscWriteLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B, scsi_busy);
6510
6511 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6512 return;
6513 } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
6514
6515 AscMemWordCopyPtrFromLram(iop_base,
6516 ASCV_MSGOUT_BEG,
6517 (uchar *)&out_msg,
6518 sizeof(EXT_MSG) >> 1);
6519
6520 if ((out_msg.msg_type == EXTENDED_MESSAGE) &&
6521 (out_msg.msg_len == MS_SDTR_LEN) &&
6522 (out_msg.msg_req == EXTENDED_SDTR)) {
6523
6524 asc_dvc->init_sdtr &= ~target_id;
6525 asc_dvc->sdtr_done &= ~target_id;
6526 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
6527 boardp->sdtr_data[tid_no] = asyn_sdtr;
6528 }
6529 q_cntl &= ~QC_MSG_OUT;
6530 AscWriteLramByte(iop_base,
6531 (ushort)(halt_q_addr +
6532 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
6533 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6534 return;
6535 } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
6536
6537 scsi_status = AscReadLramByte(iop_base,
6538 (ushort)((ushort)halt_q_addr +
6539 (ushort)
6540 ASC_SCSIQ_SCSI_STATUS));
6541 cur_dvc_qng =
6542 AscReadLramByte(iop_base,
6543 (ushort)((ushort)ASC_QADR_BEG +
6544 (ushort)target_ix));
6545 if ((cur_dvc_qng > 0) && (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
6546
6547 scsi_busy = AscReadLramByte(iop_base,
6548 (ushort)ASCV_SCSIBUSY_B);
6549 scsi_busy |= target_id;
6550 AscWriteLramByte(iop_base,
6551 (ushort)ASCV_SCSIBUSY_B, scsi_busy);
6552 asc_dvc->queue_full_or_busy |= target_id;
6553
6554 if (scsi_status == SAM_STAT_TASK_SET_FULL) {
6555 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
6556 cur_dvc_qng -= 1;
6557 asc_dvc->max_dvc_qng[tid_no] =
6558 cur_dvc_qng;
6559
6560 AscWriteLramByte(iop_base,
6561 (ushort)((ushort)
6562 ASCV_MAX_DVC_QNG_BEG
6563 + (ushort)
6564 tid_no),
6565 cur_dvc_qng);
6566
6567
6568
6569
6570
6571
6572 boardp->queue_full |= target_id;
6573 boardp->queue_full_cnt[tid_no] =
6574 cur_dvc_qng;
6575 }
6576 }
6577 }
6578 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6579 return;
6580 }
6581 return;
6582}
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594static void
6595DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
6596{
6597 int i;
6598 ushort word;
6599
6600 AscSetChipLramAddr(iop_base, s_addr);
6601 for (i = 0; i < 2 * words; i += 2) {
6602 if (i == 10) {
6603 continue;
6604 }
6605 word = inpw(iop_base + IOP_RAM_DATA);
6606 inbuf[i] = word & 0xff;
6607 inbuf[i + 1] = (word >> 8) & 0xff;
6608 }
6609 ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
6610}
6611
6612static uchar
6613_AscCopyLramScsiDoneQ(PortAddr iop_base,
6614 ushort q_addr,
6615 ASC_QDONE_INFO *scsiq, unsigned int max_dma_count)
6616{
6617 ushort _val;
6618 uchar sg_queue_cnt;
6619
6620 DvcGetQinfo(iop_base,
6621 q_addr + ASC_SCSIQ_DONE_INFO_BEG,
6622 (uchar *)scsiq,
6623 (sizeof(ASC_SCSIQ_2) + sizeof(ASC_SCSIQ_3)) / 2);
6624
6625 _val = AscReadLramWord(iop_base,
6626 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS));
6627 scsiq->q_status = (uchar)_val;
6628 scsiq->q_no = (uchar)(_val >> 8);
6629 _val = AscReadLramWord(iop_base,
6630 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_CNTL));
6631 scsiq->cntl = (uchar)_val;
6632 sg_queue_cnt = (uchar)(_val >> 8);
6633 _val = AscReadLramWord(iop_base,
6634 (ushort)(q_addr +
6635 (ushort)ASC_SCSIQ_B_SENSE_LEN));
6636 scsiq->sense_len = (uchar)_val;
6637 scsiq->extra_bytes = (uchar)(_val >> 8);
6638
6639
6640
6641
6642 scsiq->remain_bytes = (((u32)AscReadLramWord(iop_base,
6643 (ushort)(q_addr +
6644 (ushort)
6645 ASC_SCSIQ_W_ALT_DC1)))
6646 << 16);
6647
6648
6649
6650 scsiq->remain_bytes += AscReadLramWord(iop_base,
6651 (ushort)(q_addr + (ushort)
6652 ASC_SCSIQ_DW_REMAIN_XFER_CNT));
6653
6654 scsiq->remain_bytes &= max_dma_count;
6655 return sg_queue_cnt;
6656}
6657
6658
6659
6660
6661
6662
6663static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
6664{
6665 struct asc_board *boardp = asc_dvc_varp->drv_ptr;
6666 u32 srb_tag;
6667 struct scsi_cmnd *scp;
6668
6669 ASC_DBG(1, "asc_dvc_varp 0x%p, qdonep 0x%p\n", asc_dvc_varp, qdonep);
6670 ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
6671
6672
6673
6674
6675 srb_tag = qdonep->d2.srb_tag - 1;
6676 scp = scsi_host_find_tag(boardp->shost, srb_tag);
6677 if (!scp)
6678 return;
6679
6680 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
6681
6682 ASC_STATS(boardp->shost, callback);
6683
6684 dma_unmap_single(boardp->dev, scp->SCp.dma_handle,
6685 SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
6686
6687
6688
6689 scp->result = 0;
6690 switch (qdonep->d3.done_stat) {
6691 case QD_NO_ERROR:
6692 ASC_DBG(2, "QD_NO_ERROR\n");
6693
6694
6695
6696
6697
6698
6699
6700 if (scsi_bufflen(scp) != 0 && qdonep->remain_bytes != 0 &&
6701 qdonep->remain_bytes <= scsi_bufflen(scp)) {
6702 ASC_DBG(1, "underrun condition %u bytes\n",
6703 (unsigned)qdonep->remain_bytes);
6704 scsi_set_resid(scp, qdonep->remain_bytes);
6705 }
6706 break;
6707
6708 case QD_WITH_ERROR:
6709 ASC_DBG(2, "QD_WITH_ERROR\n");
6710 switch (qdonep->d3.host_stat) {
6711 case QHSTA_NO_ERROR:
6712 set_status_byte(scp, qdonep->d3.scsi_stat);
6713 if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
6714 ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n");
6715 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
6716 SCSI_SENSE_BUFFERSIZE);
6717 }
6718 break;
6719
6720 default:
6721
6722 ASC_DBG(1, "host_stat 0x%x\n", qdonep->d3.host_stat);
6723 set_host_byte(scp, DID_BAD_TARGET);
6724 break;
6725 }
6726 break;
6727
6728 case QD_ABORTED_BY_HOST:
6729 ASC_DBG(1, "QD_ABORTED_BY_HOST\n");
6730 set_status_byte(scp, qdonep->d3.scsi_stat);
6731 set_host_byte(scp, DID_ABORT);
6732 break;
6733
6734 default:
6735 ASC_DBG(1, "done_stat 0x%x\n", qdonep->d3.done_stat);
6736 set_status_byte(scp, qdonep->d3.scsi_stat);
6737 set_host_byte(scp, DID_ERROR);
6738 break;
6739 }
6740
6741
6742
6743
6744
6745
6746 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
6747 qdonep->d3.done_stat == QD_NO_ERROR &&
6748 qdonep->d3.host_stat == QHSTA_NO_ERROR) {
6749 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
6750 }
6751
6752 asc_scsi_done(scp);
6753}
6754
6755static int AscIsrQDone(ASC_DVC_VAR *asc_dvc)
6756{
6757 uchar next_qp;
6758 uchar n_q_used;
6759 uchar sg_list_qp;
6760 uchar sg_queue_cnt;
6761 uchar q_cnt;
6762 uchar done_q_tail;
6763 uchar tid_no;
6764 ASC_SCSI_BIT_ID_TYPE scsi_busy;
6765 ASC_SCSI_BIT_ID_TYPE target_id;
6766 PortAddr iop_base;
6767 ushort q_addr;
6768 ushort sg_q_addr;
6769 uchar cur_target_qng;
6770 ASC_QDONE_INFO scsiq_buf;
6771 ASC_QDONE_INFO *scsiq;
6772 bool false_overrun;
6773
6774 iop_base = asc_dvc->iop_base;
6775 n_q_used = 1;
6776 scsiq = (ASC_QDONE_INFO *)&scsiq_buf;
6777 done_q_tail = (uchar)AscGetVarDoneQTail(iop_base);
6778 q_addr = ASC_QNO_TO_QADDR(done_q_tail);
6779 next_qp = AscReadLramByte(iop_base,
6780 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_FWD));
6781 if (next_qp != ASC_QLINK_END) {
6782 AscPutVarDoneQTail(iop_base, next_qp);
6783 q_addr = ASC_QNO_TO_QADDR(next_qp);
6784 sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
6785 asc_dvc->max_dma_count);
6786 AscWriteLramByte(iop_base,
6787 (ushort)(q_addr +
6788 (ushort)ASC_SCSIQ_B_STATUS),
6789 (uchar)(scsiq->
6790 q_status & (uchar)~(QS_READY |
6791 QS_ABORTED)));
6792 tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
6793 target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
6794 if ((scsiq->cntl & QC_SG_HEAD) != 0) {
6795 sg_q_addr = q_addr;
6796 sg_list_qp = next_qp;
6797 for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
6798 sg_list_qp = AscReadLramByte(iop_base,
6799 (ushort)(sg_q_addr
6800 + (ushort)
6801 ASC_SCSIQ_B_FWD));
6802 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
6803 if (sg_list_qp == ASC_QLINK_END) {
6804 AscSetLibErrorCode(asc_dvc,
6805 ASCQ_ERR_SG_Q_LINKS);
6806 scsiq->d3.done_stat = QD_WITH_ERROR;
6807 scsiq->d3.host_stat =
6808 QHSTA_D_QDONE_SG_LIST_CORRUPTED;
6809 goto FATAL_ERR_QDONE;
6810 }
6811 AscWriteLramByte(iop_base,
6812 (ushort)(sg_q_addr + (ushort)
6813 ASC_SCSIQ_B_STATUS),
6814 QS_FREE);
6815 }
6816 n_q_used = sg_queue_cnt + 1;
6817 AscPutVarDoneQTail(iop_base, sg_list_qp);
6818 }
6819 if (asc_dvc->queue_full_or_busy & target_id) {
6820 cur_target_qng = AscReadLramByte(iop_base,
6821 (ushort)((ushort)
6822 ASC_QADR_BEG
6823 + (ushort)
6824 scsiq->d2.
6825 target_ix));
6826 if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
6827 scsi_busy = AscReadLramByte(iop_base, (ushort)
6828 ASCV_SCSIBUSY_B);
6829 scsi_busy &= ~target_id;
6830 AscWriteLramByte(iop_base,
6831 (ushort)ASCV_SCSIBUSY_B,
6832 scsi_busy);
6833 asc_dvc->queue_full_or_busy &= ~target_id;
6834 }
6835 }
6836 if (asc_dvc->cur_total_qng >= n_q_used) {
6837 asc_dvc->cur_total_qng -= n_q_used;
6838 if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
6839 asc_dvc->cur_dvc_qng[tid_no]--;
6840 }
6841 } else {
6842 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
6843 scsiq->d3.done_stat = QD_WITH_ERROR;
6844 goto FATAL_ERR_QDONE;
6845 }
6846 if ((scsiq->d2.srb_tag == 0UL) ||
6847 ((scsiq->q_status & QS_ABORTED) != 0)) {
6848 return (0x11);
6849 } else if (scsiq->q_status == QS_DONE) {
6850
6851
6852
6853
6854 false_overrun = false;
6855 if (scsiq->extra_bytes != 0) {
6856 scsiq->remain_bytes += scsiq->extra_bytes;
6857 }
6858 if (scsiq->d3.done_stat == QD_WITH_ERROR) {
6859 if (scsiq->d3.host_stat ==
6860 QHSTA_M_DATA_OVER_RUN) {
6861 if ((scsiq->
6862 cntl & (QC_DATA_IN | QC_DATA_OUT))
6863 == 0) {
6864 scsiq->d3.done_stat =
6865 QD_NO_ERROR;
6866 scsiq->d3.host_stat =
6867 QHSTA_NO_ERROR;
6868 } else if (false_overrun) {
6869 scsiq->d3.done_stat =
6870 QD_NO_ERROR;
6871 scsiq->d3.host_stat =
6872 QHSTA_NO_ERROR;
6873 }
6874 } else if (scsiq->d3.host_stat ==
6875 QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
6876 AscStopChip(iop_base);
6877 AscSetChipControl(iop_base,
6878 (uchar)(CC_SCSI_RESET
6879 | CC_HALT));
6880 udelay(60);
6881 AscSetChipControl(iop_base, CC_HALT);
6882 AscSetChipStatus(iop_base,
6883 CIW_CLR_SCSI_RESET_INT);
6884 AscSetChipStatus(iop_base, 0);
6885 AscSetChipControl(iop_base, 0);
6886 }
6887 }
6888 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
6889 asc_isr_callback(asc_dvc, scsiq);
6890 } else {
6891 if ((AscReadLramByte(iop_base,
6892 (ushort)(q_addr + (ushort)
6893 ASC_SCSIQ_CDB_BEG))
6894 == START_STOP)) {
6895 asc_dvc->unit_not_ready &= ~target_id;
6896 if (scsiq->d3.done_stat != QD_NO_ERROR) {
6897 asc_dvc->start_motor &=
6898 ~target_id;
6899 }
6900 }
6901 }
6902 return (1);
6903 } else {
6904 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
6905 FATAL_ERR_QDONE:
6906 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
6907 asc_isr_callback(asc_dvc, scsiq);
6908 }
6909 return (0x80);
6910 }
6911 }
6912 return (0);
6913}
6914
6915static int AscISR(ASC_DVC_VAR *asc_dvc)
6916{
6917 ASC_CS_TYPE chipstat;
6918 PortAddr iop_base;
6919 ushort saved_ram_addr;
6920 uchar ctrl_reg;
6921 uchar saved_ctrl_reg;
6922 int int_pending;
6923 int status;
6924 uchar host_flag;
6925
6926 iop_base = asc_dvc->iop_base;
6927 int_pending = ASC_FALSE;
6928
6929 if (AscIsIntPending(iop_base) == 0)
6930 return int_pending;
6931
6932 if ((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0) {
6933 return ASC_ERROR;
6934 }
6935 if (asc_dvc->in_critical_cnt != 0) {
6936 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
6937 return ASC_ERROR;
6938 }
6939 if (asc_dvc->is_in_int) {
6940 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
6941 return ASC_ERROR;
6942 }
6943 asc_dvc->is_in_int = true;
6944 ctrl_reg = AscGetChipControl(iop_base);
6945 saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
6946 CC_SINGLE_STEP | CC_DIAG | CC_TEST));
6947 chipstat = AscGetChipStatus(iop_base);
6948 if (chipstat & CSW_SCSI_RESET_LATCH) {
6949 if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
6950 int i = 10;
6951 int_pending = ASC_TRUE;
6952 asc_dvc->sdtr_done = 0;
6953 saved_ctrl_reg &= (uchar)(~CC_HALT);
6954 while ((AscGetChipStatus(iop_base) &
6955 CSW_SCSI_RESET_ACTIVE) && (i-- > 0)) {
6956 mdelay(100);
6957 }
6958 AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
6959 AscSetChipControl(iop_base, CC_HALT);
6960 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
6961 AscSetChipStatus(iop_base, 0);
6962 chipstat = AscGetChipStatus(iop_base);
6963 }
6964 }
6965 saved_ram_addr = AscGetChipLramAddr(iop_base);
6966 host_flag = AscReadLramByte(iop_base,
6967 ASCV_HOST_FLAG_B) &
6968 (uchar)(~ASC_HOST_FLAG_IN_ISR);
6969 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
6970 (uchar)(host_flag | (uchar)ASC_HOST_FLAG_IN_ISR));
6971 if ((chipstat & CSW_INT_PENDING) || (int_pending)) {
6972 AscAckInterrupt(iop_base);
6973 int_pending = ASC_TRUE;
6974 if ((chipstat & CSW_HALTED) && (ctrl_reg & CC_SINGLE_STEP)) {
6975 AscIsrChipHalted(asc_dvc);
6976 saved_ctrl_reg &= (uchar)(~CC_HALT);
6977 } else {
6978 if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
6979 while (((status =
6980 AscIsrQDone(asc_dvc)) & 0x01) != 0) {
6981 }
6982 } else {
6983 do {
6984 if ((status =
6985 AscIsrQDone(asc_dvc)) == 1) {
6986 break;
6987 }
6988 } while (status == 0x11);
6989 }
6990 if ((status & 0x80) != 0)
6991 int_pending = ASC_ERROR;
6992 }
6993 }
6994 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
6995 AscSetChipLramAddr(iop_base, saved_ram_addr);
6996 AscSetChipControl(iop_base, saved_ctrl_reg);
6997 asc_dvc->is_in_int = false;
6998 return int_pending;
6999}
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010static int advansys_reset(struct scsi_cmnd *scp)
7011{
7012 struct Scsi_Host *shost = scp->device->host;
7013 struct asc_board *boardp = shost_priv(shost);
7014 unsigned long flags;
7015 int status;
7016 int ret = SUCCESS;
7017
7018 ASC_DBG(1, "0x%p\n", scp);
7019
7020 ASC_STATS(shost, reset);
7021
7022 scmd_printk(KERN_INFO, scp, "SCSI host reset started...\n");
7023
7024 if (ASC_NARROW_BOARD(boardp)) {
7025 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
7026
7027
7028 ASC_DBG(1, "before AscInitAsc1000Driver()\n");
7029 status = AscInitAsc1000Driver(asc_dvc);
7030
7031
7032 if (asc_dvc->err_code || !asc_dvc->overrun_dma) {
7033 scmd_printk(KERN_INFO, scp, "SCSI host reset error: "
7034 "0x%x, status: 0x%x\n", asc_dvc->err_code,
7035 status);
7036 ret = FAILED;
7037 } else if (status) {
7038 scmd_printk(KERN_INFO, scp, "SCSI host reset warning: "
7039 "0x%x\n", status);
7040 } else {
7041 scmd_printk(KERN_INFO, scp, "SCSI host reset "
7042 "successful\n");
7043 }
7044
7045 ASC_DBG(1, "after AscInitAsc1000Driver()\n");
7046 } else {
7047
7048
7049
7050
7051 ADV_DVC_VAR *adv_dvc = &boardp->dvc_var.adv_dvc_var;
7052
7053
7054
7055
7056 ASC_DBG(1, "before AdvResetChipAndSB()\n");
7057 switch (AdvResetChipAndSB(adv_dvc)) {
7058 case ASC_TRUE:
7059 scmd_printk(KERN_INFO, scp, "SCSI host reset "
7060 "successful\n");
7061 break;
7062 case ASC_FALSE:
7063 default:
7064 scmd_printk(KERN_INFO, scp, "SCSI host reset error\n");
7065 ret = FAILED;
7066 break;
7067 }
7068 spin_lock_irqsave(shost->host_lock, flags);
7069 AdvISR(adv_dvc);
7070 spin_unlock_irqrestore(shost->host_lock, flags);
7071 }
7072
7073 ASC_DBG(1, "ret %d\n", ret);
7074
7075 return ret;
7076}
7077
7078
7079
7080
7081
7082
7083
7084
7085
7086
7087
7088
7089static int
7090advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
7091 sector_t capacity, int ip[])
7092{
7093 struct asc_board *boardp = shost_priv(sdev->host);
7094
7095 ASC_DBG(1, "begin\n");
7096 ASC_STATS(sdev->host, biosparam);
7097 if (ASC_NARROW_BOARD(boardp)) {
7098 if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
7099 ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) {
7100 ip[0] = 255;
7101 ip[1] = 63;
7102 } else {
7103 ip[0] = 64;
7104 ip[1] = 32;
7105 }
7106 } else {
7107 if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
7108 BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) {
7109 ip[0] = 255;
7110 ip[1] = 63;
7111 } else {
7112 ip[0] = 64;
7113 ip[1] = 32;
7114 }
7115 }
7116 ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
7117 ASC_DBG(1, "end\n");
7118 return 0;
7119}
7120
7121
7122
7123
7124
7125
7126static irqreturn_t advansys_interrupt(int irq, void *dev_id)
7127{
7128 struct Scsi_Host *shost = dev_id;
7129 struct asc_board *boardp = shost_priv(shost);
7130 irqreturn_t result = IRQ_NONE;
7131 unsigned long flags;
7132
7133 ASC_DBG(2, "boardp 0x%p\n", boardp);
7134 spin_lock_irqsave(shost->host_lock, flags);
7135 if (ASC_NARROW_BOARD(boardp)) {
7136 if (AscIsIntPending(shost->io_port)) {
7137 result = IRQ_HANDLED;
7138 ASC_STATS(shost, interrupt);
7139 ASC_DBG(1, "before AscISR()\n");
7140 AscISR(&boardp->dvc_var.asc_dvc_var);
7141 }
7142 } else {
7143 ASC_DBG(1, "before AdvISR()\n");
7144 if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
7145 result = IRQ_HANDLED;
7146 ASC_STATS(shost, interrupt);
7147 }
7148 }
7149 spin_unlock_irqrestore(shost->host_lock, flags);
7150
7151 ASC_DBG(1, "end\n");
7152 return result;
7153}
7154
7155static bool AscHostReqRiscHalt(PortAddr iop_base)
7156{
7157 int count = 0;
7158 bool sta = false;
7159 uchar saved_stop_code;
7160
7161 if (AscIsChipHalted(iop_base))
7162 return true;
7163 saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
7164 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
7165 ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP);
7166 do {
7167 if (AscIsChipHalted(iop_base)) {
7168 sta = true;
7169 break;
7170 }
7171 mdelay(100);
7172 } while (count++ < 20);
7173 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
7174 return sta;
7175}
7176
7177static bool
7178AscSetRunChipSynRegAtID(PortAddr iop_base, uchar tid_no, uchar sdtr_data)
7179{
7180 bool sta = false;
7181
7182 if (AscHostReqRiscHalt(iop_base)) {
7183 sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
7184 AscStartChip(iop_base);
7185 }
7186 return sta;
7187}
7188
7189static void AscAsyncFix(ASC_DVC_VAR *asc_dvc, struct scsi_device *sdev)
7190{
7191 char type = sdev->type;
7192 ASC_SCSI_BIT_ID_TYPE tid_bits = 1 << sdev->id;
7193
7194 if (!(asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN))
7195 return;
7196 if (asc_dvc->init_sdtr & tid_bits)
7197 return;
7198
7199 if ((type == TYPE_ROM) && (strncmp(sdev->vendor, "HP ", 3) == 0))
7200 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
7201
7202 asc_dvc->pci_fix_asyn_xfer |= tid_bits;
7203 if ((type == TYPE_PROCESSOR) || (type == TYPE_SCANNER) ||
7204 (type == TYPE_ROM) || (type == TYPE_TAPE))
7205 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
7206
7207 if (asc_dvc->pci_fix_asyn_xfer & tid_bits)
7208 AscSetRunChipSynRegAtID(asc_dvc->iop_base, sdev->id,
7209 ASYN_SDTR_DATA_FIX_PCI_REV_AB);
7210}
7211
7212static void
7213advansys_narrow_slave_configure(struct scsi_device *sdev, ASC_DVC_VAR *asc_dvc)
7214{
7215 ASC_SCSI_BIT_ID_TYPE tid_bit = 1 << sdev->id;
7216 ASC_SCSI_BIT_ID_TYPE orig_use_tagged_qng = asc_dvc->use_tagged_qng;
7217
7218 if (sdev->lun == 0) {
7219 ASC_SCSI_BIT_ID_TYPE orig_init_sdtr = asc_dvc->init_sdtr;
7220 if ((asc_dvc->cfg->sdtr_enable & tid_bit) && sdev->sdtr) {
7221 asc_dvc->init_sdtr |= tid_bit;
7222 } else {
7223 asc_dvc->init_sdtr &= ~tid_bit;
7224 }
7225
7226 if (orig_init_sdtr != asc_dvc->init_sdtr)
7227 AscAsyncFix(asc_dvc, sdev);
7228 }
7229
7230 if (sdev->tagged_supported) {
7231 if (asc_dvc->cfg->cmd_qng_enabled & tid_bit) {
7232 if (sdev->lun == 0) {
7233 asc_dvc->cfg->can_tagged_qng |= tid_bit;
7234 asc_dvc->use_tagged_qng |= tid_bit;
7235 }
7236 scsi_change_queue_depth(sdev,
7237 asc_dvc->max_dvc_qng[sdev->id]);
7238 }
7239 } else {
7240 if (sdev->lun == 0) {
7241 asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
7242 asc_dvc->use_tagged_qng &= ~tid_bit;
7243 }
7244 }
7245
7246 if ((sdev->lun == 0) &&
7247 (orig_use_tagged_qng != asc_dvc->use_tagged_qng)) {
7248 AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
7249 asc_dvc->cfg->disc_enable);
7250 AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
7251 asc_dvc->use_tagged_qng);
7252 AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
7253 asc_dvc->cfg->can_tagged_qng);
7254
7255 asc_dvc->max_dvc_qng[sdev->id] =
7256 asc_dvc->cfg->max_tag_qng[sdev->id];
7257 AscWriteLramByte(asc_dvc->iop_base,
7258 (ushort)(ASCV_MAX_DVC_QNG_BEG + sdev->id),
7259 asc_dvc->max_dvc_qng[sdev->id]);
7260 }
7261}
7262
7263
7264
7265
7266
7267
7268
7269
7270static void
7271advansys_wide_enable_wdtr(AdvPortAddr iop_base, unsigned short tidmask)
7272{
7273 unsigned short cfg_word;
7274 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
7275 if ((cfg_word & tidmask) != 0)
7276 return;
7277
7278 cfg_word |= tidmask;
7279 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
7280
7281
7282
7283
7284
7285
7286
7287 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
7288 cfg_word &= ~tidmask;
7289 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
7290 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
7291 cfg_word &= ~tidmask;
7292 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
7293}
7294
7295
7296
7297
7298
7299
7300
7301
7302static void
7303advansys_wide_enable_sdtr(AdvPortAddr iop_base, unsigned short tidmask)
7304{
7305 unsigned short cfg_word;
7306 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
7307 if ((cfg_word & tidmask) != 0)
7308 return;
7309
7310 cfg_word |= tidmask;
7311 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
7312
7313
7314
7315
7316
7317 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
7318 cfg_word &= ~tidmask;
7319 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
7320}
7321
7322
7323
7324
7325
7326
7327
7328
7329
7330static void advansys_wide_enable_ppr(ADV_DVC_VAR *adv_dvc,
7331 AdvPortAddr iop_base, unsigned short tidmask)
7332{
7333 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
7334 adv_dvc->ppr_able |= tidmask;
7335 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
7336}
7337
7338static void
7339advansys_wide_slave_configure(struct scsi_device *sdev, ADV_DVC_VAR *adv_dvc)
7340{
7341 AdvPortAddr iop_base = adv_dvc->iop_base;
7342 unsigned short tidmask = 1 << sdev->id;
7343
7344 if (sdev->lun == 0) {
7345
7346
7347
7348
7349
7350
7351 if ((adv_dvc->wdtr_able & tidmask) && sdev->wdtr)
7352 advansys_wide_enable_wdtr(iop_base, tidmask);
7353 if ((adv_dvc->sdtr_able & tidmask) && sdev->sdtr)
7354 advansys_wide_enable_sdtr(iop_base, tidmask);
7355 if (adv_dvc->chip_type == ADV_CHIP_ASC38C1600 && sdev->ppr)
7356 advansys_wide_enable_ppr(adv_dvc, iop_base, tidmask);
7357
7358
7359
7360
7361
7362
7363
7364 if ((adv_dvc->tagqng_able & tidmask) &&
7365 sdev->tagged_supported) {
7366 unsigned short cfg_word;
7367 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
7368 cfg_word |= tidmask;
7369 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
7370 cfg_word);
7371 AdvWriteByteLram(iop_base,
7372 ASC_MC_NUMBER_OF_MAX_CMD + sdev->id,
7373 adv_dvc->max_dvc_qng);
7374 }
7375 }
7376
7377 if ((adv_dvc->tagqng_able & tidmask) && sdev->tagged_supported)
7378 scsi_change_queue_depth(sdev, adv_dvc->max_dvc_qng);
7379}
7380
7381
7382
7383
7384
7385static int advansys_slave_configure(struct scsi_device *sdev)
7386{
7387 struct asc_board *boardp = shost_priv(sdev->host);
7388
7389 if (ASC_NARROW_BOARD(boardp))
7390 advansys_narrow_slave_configure(sdev,
7391 &boardp->dvc_var.asc_dvc_var);
7392 else
7393 advansys_wide_slave_configure(sdev,
7394 &boardp->dvc_var.adv_dvc_var);
7395
7396 return 0;
7397}
7398
7399static __le32 asc_get_sense_buffer_dma(struct scsi_cmnd *scp)
7400{
7401 struct asc_board *board = shost_priv(scp->device->host);
7402
7403 scp->SCp.dma_handle = dma_map_single(board->dev, scp->sense_buffer,
7404 SCSI_SENSE_BUFFERSIZE,
7405 DMA_FROM_DEVICE);
7406 if (dma_mapping_error(board->dev, scp->SCp.dma_handle)) {
7407 ASC_DBG(1, "failed to map sense buffer\n");
7408 return 0;
7409 }
7410 return cpu_to_le32(scp->SCp.dma_handle);
7411}
7412
7413static int asc_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,
7414 struct asc_scsi_q *asc_scsi_q)
7415{
7416 struct asc_dvc_var *asc_dvc = &boardp->dvc_var.asc_dvc_var;
7417 int use_sg;
7418 u32 srb_tag;
7419
7420 memset(asc_scsi_q, 0, sizeof(*asc_scsi_q));
7421
7422
7423
7424
7425
7426 srb_tag = scsi_cmd_to_rq(scp)->tag + 1;
7427 asc_scsi_q->q2.srb_tag = srb_tag;
7428
7429
7430
7431
7432 asc_scsi_q->cdbptr = &scp->cmnd[0];
7433 asc_scsi_q->q2.cdb_len = scp->cmd_len;
7434 asc_scsi_q->q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
7435 asc_scsi_q->q1.target_lun = scp->device->lun;
7436 asc_scsi_q->q2.target_ix =
7437 ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
7438 asc_scsi_q->q1.sense_addr = asc_get_sense_buffer_dma(scp);
7439 asc_scsi_q->q1.sense_len = SCSI_SENSE_BUFFERSIZE;
7440 if (!asc_scsi_q->q1.sense_addr)
7441 return ASC_BUSY;
7442
7443
7444
7445
7446
7447
7448
7449
7450
7451
7452
7453
7454 if ((asc_dvc->cur_dvc_qng[scp->device->id] > 0) &&
7455 (boardp->reqcnt[scp->device->id] % 255) == 0) {
7456 asc_scsi_q->q2.tag_code = ORDERED_QUEUE_TAG;
7457 } else {
7458 asc_scsi_q->q2.tag_code = SIMPLE_QUEUE_TAG;
7459 }
7460
7461
7462 use_sg = scsi_dma_map(scp);
7463 if (use_sg < 0) {
7464 ASC_DBG(1, "failed to map sglist\n");
7465 return ASC_BUSY;
7466 } else if (use_sg > 0) {
7467 int sgcnt;
7468 struct scatterlist *slp;
7469 struct asc_sg_head *asc_sg_head;
7470
7471 if (use_sg > scp->device->host->sg_tablesize) {
7472 scmd_printk(KERN_ERR, scp, "use_sg %d > "
7473 "sg_tablesize %d\n", use_sg,
7474 scp->device->host->sg_tablesize);
7475 scsi_dma_unmap(scp);
7476 set_host_byte(scp, DID_ERROR);
7477 return ASC_ERROR;
7478 }
7479
7480 asc_sg_head = kzalloc(sizeof(asc_scsi_q->sg_head) +
7481 use_sg * sizeof(struct asc_sg_list), GFP_ATOMIC);
7482 if (!asc_sg_head) {
7483 scsi_dma_unmap(scp);
7484 set_host_byte(scp, DID_SOFT_ERROR);
7485 return ASC_ERROR;
7486 }
7487
7488 asc_scsi_q->q1.cntl |= QC_SG_HEAD;
7489 asc_scsi_q->sg_head = asc_sg_head;
7490 asc_scsi_q->q1.data_cnt = 0;
7491 asc_scsi_q->q1.data_addr = 0;
7492
7493 asc_sg_head->entry_cnt = asc_scsi_q->q1.sg_queue_cnt = use_sg;
7494 ASC_STATS_ADD(scp->device->host, xfer_elem,
7495 asc_sg_head->entry_cnt);
7496
7497
7498
7499
7500 scsi_for_each_sg(scp, slp, use_sg, sgcnt) {
7501 asc_sg_head->sg_list[sgcnt].addr =
7502 cpu_to_le32(sg_dma_address(slp));
7503 asc_sg_head->sg_list[sgcnt].bytes =
7504 cpu_to_le32(sg_dma_len(slp));
7505 ASC_STATS_ADD(scp->device->host, xfer_sect,
7506 DIV_ROUND_UP(sg_dma_len(slp), 512));
7507 }
7508 }
7509
7510 ASC_STATS(scp->device->host, xfer_cnt);
7511
7512 ASC_DBG_PRT_ASC_SCSI_Q(2, asc_scsi_q);
7513 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
7514
7515 return ASC_NOERROR;
7516}
7517
7518
7519
7520
7521
7522
7523
7524
7525
7526
7527
7528
7529
7530static int
7531adv_get_sglist(struct asc_board *boardp, adv_req_t *reqp,
7532 ADV_SCSI_REQ_Q *scsiqp, struct scsi_cmnd *scp, int use_sg)
7533{
7534 adv_sgblk_t *sgblkp, *prev_sgblkp;
7535 struct scatterlist *slp;
7536 int sg_elem_cnt;
7537 ADV_SG_BLOCK *sg_block, *prev_sg_block;
7538 dma_addr_t sgblk_paddr;
7539 int i;
7540
7541 slp = scsi_sglist(scp);
7542 sg_elem_cnt = use_sg;
7543 prev_sgblkp = NULL;
7544 prev_sg_block = NULL;
7545 reqp->sgblkp = NULL;
7546
7547 for (;;) {
7548
7549
7550
7551
7552
7553 sgblkp = dma_pool_alloc(boardp->adv_sgblk_pool, GFP_ATOMIC,
7554 &sgblk_paddr);
7555 if (!sgblkp) {
7556 ASC_DBG(1, "no free adv_sgblk_t\n");
7557 ASC_STATS(scp->device->host, adv_build_nosg);
7558
7559
7560
7561
7562
7563 while ((sgblkp = reqp->sgblkp) != NULL) {
7564
7565 reqp->sgblkp = sgblkp->next_sgblkp;
7566 sgblkp->next_sgblkp = NULL;
7567 dma_pool_free(boardp->adv_sgblk_pool, sgblkp,
7568 sgblkp->sg_addr);
7569 }
7570 return ASC_BUSY;
7571 }
7572
7573 sgblkp->sg_addr = sgblk_paddr;
7574 sgblkp->next_sgblkp = NULL;
7575 sg_block = &sgblkp->sg_block;
7576
7577
7578
7579
7580
7581 if (reqp->sgblkp == NULL) {
7582
7583 reqp->sgblkp = sgblkp;
7584
7585
7586
7587
7588
7589 scsiqp->sg_list_ptr = sg_block;
7590 scsiqp->sg_real_addr = cpu_to_le32(sgblk_paddr);
7591 } else {
7592
7593 prev_sgblkp->next_sgblkp = sgblkp;
7594
7595
7596
7597
7598
7599 prev_sg_block->sg_ptr = cpu_to_le32(sgblk_paddr);
7600 }
7601
7602 for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) {
7603 sg_block->sg_list[i].sg_addr =
7604 cpu_to_le32(sg_dma_address(slp));
7605 sg_block->sg_list[i].sg_count =
7606 cpu_to_le32(sg_dma_len(slp));
7607 ASC_STATS_ADD(scp->device->host, xfer_sect,
7608 DIV_ROUND_UP(sg_dma_len(slp), 512));
7609
7610 if (--sg_elem_cnt == 0) {
7611
7612
7613
7614 sg_block->sg_cnt = i + 1;
7615 sg_block->sg_ptr = 0L;
7616 return ADV_SUCCESS;
7617 }
7618 slp = sg_next(slp);
7619 }
7620 sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
7621 prev_sg_block = sg_block;
7622 prev_sgblkp = sgblkp;
7623 }
7624}
7625
7626
7627
7628
7629
7630
7631
7632
7633
7634
7635
7636static int
7637adv_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,
7638 adv_req_t **adv_reqpp)
7639{
7640 u32 srb_tag = scsi_cmd_to_rq(scp)->tag;
7641 adv_req_t *reqp;
7642 ADV_SCSI_REQ_Q *scsiqp;
7643 int ret;
7644 int use_sg;
7645 dma_addr_t sense_addr;
7646
7647
7648
7649
7650
7651 reqp = &boardp->adv_reqp[srb_tag];
7652 if (reqp->cmndp && reqp->cmndp != scp ) {
7653 ASC_DBG(1, "no free adv_req_t\n");
7654 ASC_STATS(scp->device->host, adv_build_noreq);
7655 return ASC_BUSY;
7656 }
7657
7658 reqp->req_addr = boardp->adv_reqp_addr + (srb_tag * sizeof(adv_req_t));
7659
7660 scsiqp = &reqp->scsi_req_q;
7661
7662
7663
7664
7665 scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
7666
7667
7668
7669
7670 scsiqp->srb_tag = srb_tag;
7671
7672
7673
7674
7675 reqp->cmndp = scp;
7676 scp->host_scribble = (void *)reqp;
7677
7678
7679
7680
7681
7682
7683 scsiqp->cdb_len = scp->cmd_len;
7684
7685 memcpy(scsiqp->cdb, scp->cmnd, scp->cmd_len < 12 ? scp->cmd_len : 12);
7686
7687 if (scp->cmd_len > 12) {
7688 int cdb16_len = scp->cmd_len - 12;
7689
7690 memcpy(scsiqp->cdb16, &scp->cmnd[12], cdb16_len);
7691 }
7692
7693 scsiqp->target_id = scp->device->id;
7694 scsiqp->target_lun = scp->device->lun;
7695
7696 sense_addr = dma_map_single(boardp->dev, scp->sense_buffer,
7697 SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
7698 if (dma_mapping_error(boardp->dev, sense_addr)) {
7699 ASC_DBG(1, "failed to map sense buffer\n");
7700 ASC_STATS(scp->device->host, adv_build_noreq);
7701 return ASC_BUSY;
7702 }
7703 scsiqp->sense_addr = cpu_to_le32(sense_addr);
7704 scsiqp->sense_len = SCSI_SENSE_BUFFERSIZE;
7705
7706
7707
7708 use_sg = scsi_dma_map(scp);
7709 if (use_sg < 0) {
7710 ASC_DBG(1, "failed to map SG list\n");
7711 ASC_STATS(scp->device->host, adv_build_noreq);
7712 return ASC_BUSY;
7713 } else if (use_sg == 0) {
7714
7715 reqp->sgblkp = NULL;
7716 scsiqp->data_cnt = 0;
7717
7718 scsiqp->data_addr = 0;
7719 scsiqp->sg_list_ptr = NULL;
7720 scsiqp->sg_real_addr = 0;
7721 } else {
7722 if (use_sg > ADV_MAX_SG_LIST) {
7723 scmd_printk(KERN_ERR, scp, "use_sg %d > "
7724 "ADV_MAX_SG_LIST %d\n", use_sg,
7725 scp->device->host->sg_tablesize);
7726 scsi_dma_unmap(scp);
7727 set_host_byte(scp, DID_ERROR);
7728 reqp->cmndp = NULL;
7729 scp->host_scribble = NULL;
7730
7731 return ASC_ERROR;
7732 }
7733
7734 scsiqp->data_cnt = cpu_to_le32(scsi_bufflen(scp));
7735
7736 ret = adv_get_sglist(boardp, reqp, scsiqp, scp, use_sg);
7737 if (ret != ADV_SUCCESS) {
7738 scsi_dma_unmap(scp);
7739 set_host_byte(scp, DID_ERROR);
7740 reqp->cmndp = NULL;
7741 scp->host_scribble = NULL;
7742
7743 return ret;
7744 }
7745
7746 ASC_STATS_ADD(scp->device->host, xfer_elem, use_sg);
7747 }
7748
7749 ASC_STATS(scp->device->host, xfer_cnt);
7750
7751 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
7752 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
7753
7754 *adv_reqpp = reqp;
7755
7756 return ASC_NOERROR;
7757}
7758
7759static int AscSgListToQueue(int sg_list)
7760{
7761 int n_sg_list_qs;
7762
7763 n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
7764 if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
7765 n_sg_list_qs++;
7766 return n_sg_list_qs + 1;
7767}
7768
7769static uint
7770AscGetNumOfFreeQueue(ASC_DVC_VAR *asc_dvc, uchar target_ix, uchar n_qs)
7771{
7772 uint cur_used_qs;
7773 uint cur_free_qs;
7774 ASC_SCSI_BIT_ID_TYPE target_id;
7775 uchar tid_no;
7776
7777 target_id = ASC_TIX_TO_TARGET_ID(target_ix);
7778 tid_no = ASC_TIX_TO_TID(target_ix);
7779 if ((asc_dvc->unit_not_ready & target_id) ||
7780 (asc_dvc->queue_full_or_busy & target_id)) {
7781 return 0;
7782 }
7783 if (n_qs == 1) {
7784 cur_used_qs = (uint) asc_dvc->cur_total_qng +
7785 (uint) asc_dvc->last_q_shortage + (uint) ASC_MIN_FREE_Q;
7786 } else {
7787 cur_used_qs = (uint) asc_dvc->cur_total_qng +
7788 (uint) ASC_MIN_FREE_Q;
7789 }
7790 if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
7791 cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
7792 if (asc_dvc->cur_dvc_qng[tid_no] >=
7793 asc_dvc->max_dvc_qng[tid_no]) {
7794 return 0;
7795 }
7796 return cur_free_qs;
7797 }
7798 if (n_qs > 1) {
7799 if ((n_qs > asc_dvc->last_q_shortage)
7800 && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
7801 asc_dvc->last_q_shortage = n_qs;
7802 }
7803 }
7804 return 0;
7805}
7806
7807static uchar AscAllocFreeQueue(PortAddr iop_base, uchar free_q_head)
7808{
7809 ushort q_addr;
7810 uchar next_qp;
7811 uchar q_status;
7812
7813 q_addr = ASC_QNO_TO_QADDR(free_q_head);
7814 q_status = (uchar)AscReadLramByte(iop_base,
7815 (ushort)(q_addr +
7816 ASC_SCSIQ_B_STATUS));
7817 next_qp = AscReadLramByte(iop_base, (ushort)(q_addr + ASC_SCSIQ_B_FWD));
7818 if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END))
7819 return next_qp;
7820 return ASC_QLINK_END;
7821}
7822
7823static uchar
7824AscAllocMultipleFreeQueue(PortAddr iop_base, uchar free_q_head, uchar n_free_q)
7825{
7826 uchar i;
7827
7828 for (i = 0; i < n_free_q; i++) {
7829 free_q_head = AscAllocFreeQueue(iop_base, free_q_head);
7830 if (free_q_head == ASC_QLINK_END)
7831 break;
7832 }
7833 return free_q_head;
7834}
7835
7836
7837
7838
7839
7840
7841
7842
7843
7844
7845
7846static void
7847DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
7848{
7849 int i;
7850
7851 ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
7852 AscSetChipLramAddr(iop_base, s_addr);
7853 for (i = 0; i < 2 * words; i += 2) {
7854 if (i == 4 || i == 20) {
7855 continue;
7856 }
7857 outpw(iop_base + IOP_RAM_DATA,
7858 ((ushort)outbuf[i + 1] << 8) | outbuf[i]);
7859 }
7860}
7861
7862static int AscPutReadyQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
7863{
7864 ushort q_addr;
7865 uchar tid_no;
7866 uchar sdtr_data;
7867 uchar syn_period_ix;
7868 uchar syn_offset;
7869 PortAddr iop_base;
7870
7871 iop_base = asc_dvc->iop_base;
7872 if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
7873 ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
7874 tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
7875 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
7876 syn_period_ix =
7877 (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
7878 syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
7879 AscMsgOutSDTR(asc_dvc,
7880 asc_dvc->sdtr_period_tbl[syn_period_ix],
7881 syn_offset);
7882 scsiq->q1.cntl |= QC_MSG_OUT;
7883 }
7884 q_addr = ASC_QNO_TO_QADDR(q_no);
7885 if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
7886 scsiq->q2.tag_code &= ~SIMPLE_QUEUE_TAG;
7887 }
7888 scsiq->q1.status = QS_FREE;
7889 AscMemWordCopyPtrToLram(iop_base,
7890 q_addr + ASC_SCSIQ_CDB_BEG,
7891 (uchar *)scsiq->cdbptr, scsiq->q2.cdb_len >> 1);
7892
7893 DvcPutScsiQ(iop_base,
7894 q_addr + ASC_SCSIQ_CPY_BEG,
7895 (uchar *)&scsiq->q1.cntl,
7896 ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
7897 AscWriteLramWord(iop_base,
7898 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS),
7899 (ushort)(((ushort)scsiq->q1.
7900 q_no << 8) | (ushort)QS_READY));
7901 return 1;
7902}
7903
7904static int
7905AscPutReadySgListQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
7906{
7907 int sta;
7908 int i;
7909 ASC_SG_HEAD *sg_head;
7910 ASC_SG_LIST_Q scsi_sg_q;
7911 __le32 saved_data_addr;
7912 __le32 saved_data_cnt;
7913 PortAddr iop_base;
7914 ushort sg_list_dwords;
7915 ushort sg_index;
7916 ushort sg_entry_cnt;
7917 ushort q_addr;
7918 uchar next_qp;
7919
7920 iop_base = asc_dvc->iop_base;
7921 sg_head = scsiq->sg_head;
7922 saved_data_addr = scsiq->q1.data_addr;
7923 saved_data_cnt = scsiq->q1.data_cnt;
7924 scsiq->q1.data_addr = cpu_to_le32(sg_head->sg_list[0].addr);
7925 scsiq->q1.data_cnt = cpu_to_le32(sg_head->sg_list[0].bytes);
7926
7927
7928
7929
7930
7931 sg_entry_cnt = sg_head->entry_cnt - 1;
7932
7933 if (sg_entry_cnt != 0) {
7934 scsiq->q1.cntl |= QC_SG_HEAD;
7935 q_addr = ASC_QNO_TO_QADDR(q_no);
7936 sg_index = 1;
7937 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
7938 scsi_sg_q.sg_head_qp = q_no;
7939 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
7940 for (i = 0; i < sg_head->queue_cnt; i++) {
7941 scsi_sg_q.seq_no = i + 1;
7942 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
7943 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
7944 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
7945 if (i == 0) {
7946 scsi_sg_q.sg_list_cnt =
7947 ASC_SG_LIST_PER_Q;
7948 scsi_sg_q.sg_cur_list_cnt =
7949 ASC_SG_LIST_PER_Q;
7950 } else {
7951 scsi_sg_q.sg_list_cnt =
7952 ASC_SG_LIST_PER_Q - 1;
7953 scsi_sg_q.sg_cur_list_cnt =
7954 ASC_SG_LIST_PER_Q - 1;
7955 }
7956 } else {
7957 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
7958 sg_list_dwords = sg_entry_cnt << 1;
7959 if (i == 0) {
7960 scsi_sg_q.sg_list_cnt = sg_entry_cnt;
7961 scsi_sg_q.sg_cur_list_cnt =
7962 sg_entry_cnt;
7963 } else {
7964 scsi_sg_q.sg_list_cnt =
7965 sg_entry_cnt - 1;
7966 scsi_sg_q.sg_cur_list_cnt =
7967 sg_entry_cnt - 1;
7968 }
7969 sg_entry_cnt = 0;
7970 }
7971 next_qp = AscReadLramByte(iop_base,
7972 (ushort)(q_addr +
7973 ASC_SCSIQ_B_FWD));
7974 scsi_sg_q.q_no = next_qp;
7975 q_addr = ASC_QNO_TO_QADDR(next_qp);
7976 AscMemWordCopyPtrToLram(iop_base,
7977 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
7978 (uchar *)&scsi_sg_q,
7979 sizeof(ASC_SG_LIST_Q) >> 1);
7980 AscMemDWordCopyPtrToLram(iop_base,
7981 q_addr + ASC_SGQ_LIST_BEG,
7982 (uchar *)&sg_head->
7983 sg_list[sg_index],
7984 sg_list_dwords);
7985 sg_index += ASC_SG_LIST_PER_Q;
7986 scsiq->next_sg_index = sg_index;
7987 }
7988 } else {
7989 scsiq->q1.cntl &= ~QC_SG_HEAD;
7990 }
7991 sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
7992 scsiq->q1.data_addr = saved_data_addr;
7993 scsiq->q1.data_cnt = saved_data_cnt;
7994 return (sta);
7995}
7996
7997static int
7998AscSendScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar n_q_required)
7999{
8000 PortAddr iop_base;
8001 uchar free_q_head;
8002 uchar next_qp;
8003 uchar tid_no;
8004 uchar target_ix;
8005 int sta;
8006
8007 iop_base = asc_dvc->iop_base;
8008 target_ix = scsiq->q2.target_ix;
8009 tid_no = ASC_TIX_TO_TID(target_ix);
8010 sta = 0;
8011 free_q_head = (uchar)AscGetVarFreeQHead(iop_base);
8012 if (n_q_required > 1) {
8013 next_qp = AscAllocMultipleFreeQueue(iop_base, free_q_head,
8014 (uchar)n_q_required);
8015 if (next_qp != ASC_QLINK_END) {
8016 asc_dvc->last_q_shortage = 0;
8017 scsiq->sg_head->queue_cnt = n_q_required - 1;
8018 scsiq->q1.q_no = free_q_head;
8019 sta = AscPutReadySgListQueue(asc_dvc, scsiq,
8020 free_q_head);
8021 }
8022 } else if (n_q_required == 1) {
8023 next_qp = AscAllocFreeQueue(iop_base, free_q_head);
8024 if (next_qp != ASC_QLINK_END) {
8025 scsiq->q1.q_no = free_q_head;
8026 sta = AscPutReadyQueue(asc_dvc, scsiq, free_q_head);
8027 }
8028 }
8029 if (sta == 1) {
8030 AscPutVarFreeQHead(iop_base, next_qp);
8031 asc_dvc->cur_total_qng += n_q_required;
8032 asc_dvc->cur_dvc_qng[tid_no]++;
8033 }
8034 return sta;
8035}
8036
8037#define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16
8038static uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = {
8039 INQUIRY,
8040 REQUEST_SENSE,
8041 READ_CAPACITY,
8042 READ_TOC,
8043 MODE_SELECT,
8044 MODE_SENSE,
8045 MODE_SELECT_10,
8046 MODE_SENSE_10,
8047 0xFF,
8048 0xFF,
8049 0xFF,
8050 0xFF,
8051 0xFF,
8052 0xFF,
8053 0xFF,
8054 0xFF
8055};
8056
8057static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq)
8058{
8059 PortAddr iop_base;
8060 int sta;
8061 int n_q_required;
8062 bool disable_syn_offset_one_fix;
8063 int i;
8064 u32 addr;
8065 ushort sg_entry_cnt = 0;
8066 ushort sg_entry_cnt_minus_one = 0;
8067 uchar target_ix;
8068 uchar tid_no;
8069 uchar sdtr_data;
8070 uchar extra_bytes;
8071 uchar scsi_cmd;
8072 uchar disable_cmd;
8073 ASC_SG_HEAD *sg_head;
8074 unsigned long data_cnt;
8075
8076 iop_base = asc_dvc->iop_base;
8077 sg_head = scsiq->sg_head;
8078 if (asc_dvc->err_code != 0)
8079 return ASC_ERROR;
8080 scsiq->q1.q_no = 0;
8081 if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
8082 scsiq->q1.extra_bytes = 0;
8083 }
8084 sta = 0;
8085 target_ix = scsiq->q2.target_ix;
8086 tid_no = ASC_TIX_TO_TID(target_ix);
8087 n_q_required = 1;
8088 if (scsiq->cdbptr[0] == REQUEST_SENSE) {
8089 if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
8090 asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
8091 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
8092 AscMsgOutSDTR(asc_dvc,
8093 asc_dvc->
8094 sdtr_period_tbl[(sdtr_data >> 4) &
8095 (uchar)(asc_dvc->
8096 max_sdtr_index -
8097 1)],
8098 (uchar)(sdtr_data & (uchar)
8099 ASC_SYN_MAX_OFFSET));
8100 scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
8101 }
8102 }
8103 if (asc_dvc->in_critical_cnt != 0) {
8104 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
8105 return ASC_ERROR;
8106 }
8107 asc_dvc->in_critical_cnt++;
8108 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
8109 if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
8110 asc_dvc->in_critical_cnt--;
8111 return ASC_ERROR;
8112 }
8113 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
8114 asc_dvc->in_critical_cnt--;
8115 return ASC_ERROR;
8116 }
8117 if (sg_entry_cnt == 1) {
8118 scsiq->q1.data_addr = cpu_to_le32(sg_head->sg_list[0].addr);
8119 scsiq->q1.data_cnt = cpu_to_le32(sg_head->sg_list[0].bytes);
8120 scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
8121 }
8122 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
8123 }
8124 scsi_cmd = scsiq->cdbptr[0];
8125 disable_syn_offset_one_fix = false;
8126 if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
8127 !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
8128 if (scsiq->q1.cntl & QC_SG_HEAD) {
8129 data_cnt = 0;
8130 for (i = 0; i < sg_entry_cnt; i++) {
8131 data_cnt += le32_to_cpu(sg_head->sg_list[i].
8132 bytes);
8133 }
8134 } else {
8135 data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
8136 }
8137 if (data_cnt != 0UL) {
8138 if (data_cnt < 512UL) {
8139 disable_syn_offset_one_fix = true;
8140 } else {
8141 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST;
8142 i++) {
8143 disable_cmd =
8144 _syn_offset_one_disable_cmd[i];
8145 if (disable_cmd == 0xFF) {
8146 break;
8147 }
8148 if (scsi_cmd == disable_cmd) {
8149 disable_syn_offset_one_fix =
8150 true;
8151 break;
8152 }
8153 }
8154 }
8155 }
8156 }
8157 if (disable_syn_offset_one_fix) {
8158 scsiq->q2.tag_code &= ~SIMPLE_QUEUE_TAG;
8159 scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
8160 ASC_TAG_FLAG_DISABLE_DISCONNECT);
8161 } else {
8162 scsiq->q2.tag_code &= 0x27;
8163 }
8164 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
8165 if (asc_dvc->bug_fix_cntl) {
8166 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
8167 if ((scsi_cmd == READ_6) ||
8168 (scsi_cmd == READ_10)) {
8169 addr = le32_to_cpu(sg_head->
8170 sg_list
8171 [sg_entry_cnt_minus_one].
8172 addr) +
8173 le32_to_cpu(sg_head->
8174 sg_list
8175 [sg_entry_cnt_minus_one].
8176 bytes);
8177 extra_bytes =
8178 (uchar)((ushort)addr & 0x0003);
8179 if ((extra_bytes != 0)
8180 &&
8181 ((scsiq->q2.
8182 tag_code &
8183 ASC_TAG_FLAG_EXTRA_BYTES)
8184 == 0)) {
8185 scsiq->q2.tag_code |=
8186 ASC_TAG_FLAG_EXTRA_BYTES;
8187 scsiq->q1.extra_bytes =
8188 extra_bytes;
8189 data_cnt =
8190 le32_to_cpu(sg_head->
8191 sg_list
8192 [sg_entry_cnt_minus_one].
8193 bytes);
8194 data_cnt -= extra_bytes;
8195 sg_head->
8196 sg_list
8197 [sg_entry_cnt_minus_one].
8198 bytes =
8199 cpu_to_le32(data_cnt);
8200 }
8201 }
8202 }
8203 }
8204 sg_head->entry_to_copy = sg_head->entry_cnt;
8205 n_q_required = AscSgListToQueue(sg_entry_cnt);
8206 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
8207 (uint) n_q_required)
8208 || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
8209 if ((sta =
8210 AscSendScsiQueue(asc_dvc, scsiq,
8211 n_q_required)) == 1) {
8212 asc_dvc->in_critical_cnt--;
8213 return (sta);
8214 }
8215 }
8216 } else {
8217 if (asc_dvc->bug_fix_cntl) {
8218 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
8219 if ((scsi_cmd == READ_6) ||
8220 (scsi_cmd == READ_10)) {
8221 addr =
8222 le32_to_cpu(scsiq->q1.data_addr) +
8223 le32_to_cpu(scsiq->q1.data_cnt);
8224 extra_bytes =
8225 (uchar)((ushort)addr & 0x0003);
8226 if ((extra_bytes != 0)
8227 &&
8228 ((scsiq->q2.
8229 tag_code &
8230 ASC_TAG_FLAG_EXTRA_BYTES)
8231 == 0)) {
8232 data_cnt =
8233 le32_to_cpu(scsiq->q1.
8234 data_cnt);
8235 if (((ushort)data_cnt & 0x01FF)
8236 == 0) {
8237 scsiq->q2.tag_code |=
8238 ASC_TAG_FLAG_EXTRA_BYTES;
8239 data_cnt -= extra_bytes;
8240 scsiq->q1.data_cnt =
8241 cpu_to_le32
8242 (data_cnt);
8243 scsiq->q1.extra_bytes =
8244 extra_bytes;
8245 }
8246 }
8247 }
8248 }
8249 }
8250 n_q_required = 1;
8251 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
8252 ((scsiq->q1.cntl & QC_URGENT) != 0)) {
8253 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
8254 n_q_required)) == 1) {
8255 asc_dvc->in_critical_cnt--;
8256 return (sta);
8257 }
8258 }
8259 }
8260 asc_dvc->in_critical_cnt--;
8261 return (sta);
8262}
8263
8264
8265
8266
8267
8268
8269
8270
8271
8272
8273
8274
8275
8276
8277
8278
8279
8280
8281
8282
8283
8284
8285static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, adv_req_t *reqp)
8286{
8287 AdvPortAddr iop_base;
8288 ADV_CARR_T *new_carrp;
8289 ADV_SCSI_REQ_Q *scsiq = &reqp->scsi_req_q;
8290
8291
8292
8293
8294 if (scsiq->target_id > ADV_MAX_TID) {
8295 scsiq->host_status = QHSTA_M_INVALID_DEVICE;
8296 scsiq->done_status = QD_WITH_ERROR;
8297 return ADV_ERROR;
8298 }
8299
8300 iop_base = asc_dvc->iop_base;
8301
8302
8303
8304
8305
8306 new_carrp = adv_get_next_carrier(asc_dvc);
8307 if (!new_carrp) {
8308 ASC_DBG(1, "No free carriers\n");
8309 return ADV_BUSY;
8310 }
8311
8312 asc_dvc->carr_pending_cnt++;
8313
8314
8315 scsiq->scsiq_ptr = cpu_to_le32(scsiq->srb_tag);
8316 scsiq->scsiq_rptr = cpu_to_le32(reqp->req_addr);
8317
8318 scsiq->carr_va = asc_dvc->icq_sp->carr_va;
8319 scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
8320
8321
8322
8323
8324
8325
8326 asc_dvc->icq_sp->areq_vpa = scsiq->scsiq_rptr;
8327
8328
8329
8330
8331
8332
8333 asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
8334
8335
8336
8337
8338 asc_dvc->icq_sp = new_carrp;
8339
8340 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
8341 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
8342
8343
8344
8345 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
8346 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
8347
8348
8349
8350
8351
8352 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
8353 ADV_TICKLE_NOP);
8354 }
8355 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
8356
8357
8358
8359
8360 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
8361 le32_to_cpu(new_carrp->carr_pa));
8362 }
8363
8364 return ADV_SUCCESS;
8365}
8366
8367
8368
8369
8370static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
8371{
8372 int ret, err_code;
8373 struct asc_board *boardp = shost_priv(scp->device->host);
8374
8375 ASC_DBG(1, "scp 0x%p\n", scp);
8376
8377 if (ASC_NARROW_BOARD(boardp)) {
8378 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
8379 struct asc_scsi_q asc_scsi_q;
8380
8381 ret = asc_build_req(boardp, scp, &asc_scsi_q);
8382 if (ret != ASC_NOERROR) {
8383 ASC_STATS(scp->device->host, build_error);
8384 return ret;
8385 }
8386
8387 ret = AscExeScsiQueue(asc_dvc, &asc_scsi_q);
8388 kfree(asc_scsi_q.sg_head);
8389 err_code = asc_dvc->err_code;
8390 } else {
8391 ADV_DVC_VAR *adv_dvc = &boardp->dvc_var.adv_dvc_var;
8392 adv_req_t *adv_reqp;
8393
8394 switch (adv_build_req(boardp, scp, &adv_reqp)) {
8395 case ASC_NOERROR:
8396 ASC_DBG(3, "adv_build_req ASC_NOERROR\n");
8397 break;
8398 case ASC_BUSY:
8399 ASC_DBG(1, "adv_build_req ASC_BUSY\n");
8400
8401
8402
8403
8404
8405
8406 return ASC_BUSY;
8407 case ASC_ERROR:
8408 default:
8409 ASC_DBG(1, "adv_build_req ASC_ERROR\n");
8410 ASC_STATS(scp->device->host, build_error);
8411 return ASC_ERROR;
8412 }
8413
8414 ret = AdvExeScsiQueue(adv_dvc, adv_reqp);
8415 err_code = adv_dvc->err_code;
8416 }
8417
8418 switch (ret) {
8419 case ASC_NOERROR:
8420 ASC_STATS(scp->device->host, exe_noerror);
8421
8422
8423
8424
8425 boardp->reqcnt[scp->device->id]++;
8426 ASC_DBG(1, "ExeScsiQueue() ASC_NOERROR\n");
8427 break;
8428 case ASC_BUSY:
8429 ASC_DBG(1, "ExeScsiQueue() ASC_BUSY\n");
8430 ASC_STATS(scp->device->host, exe_busy);
8431 break;
8432 case ASC_ERROR:
8433 scmd_printk(KERN_ERR, scp, "ExeScsiQueue() ASC_ERROR, "
8434 "err_code 0x%x\n", err_code);
8435 ASC_STATS(scp->device->host, exe_error);
8436 set_host_byte(scp, DID_ERROR);
8437 break;
8438 default:
8439 scmd_printk(KERN_ERR, scp, "ExeScsiQueue() unknown, "
8440 "err_code 0x%x\n", err_code);
8441 ASC_STATS(scp->device->host, exe_unknown);
8442 set_host_byte(scp, DID_ERROR);
8443 break;
8444 }
8445
8446 ASC_DBG(1, "end\n");
8447 return ret;
8448}
8449
8450
8451
8452
8453
8454
8455
8456static int
8457advansys_queuecommand_lck(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
8458{
8459 struct Scsi_Host *shost = scp->device->host;
8460 int asc_res, result = 0;
8461
8462 ASC_STATS(shost, queuecommand);
8463 scp->scsi_done = done;
8464
8465 asc_res = asc_execute_scsi_cmnd(scp);
8466
8467 switch (asc_res) {
8468 case ASC_NOERROR:
8469 break;
8470 case ASC_BUSY:
8471 result = SCSI_MLQUEUE_HOST_BUSY;
8472 break;
8473 case ASC_ERROR:
8474 default:
8475 asc_scsi_done(scp);
8476 break;
8477 }
8478
8479 return result;
8480}
8481
8482static DEF_SCSI_QCMD(advansys_queuecommand)
8483
8484static ushort AscGetEisaChipCfg(PortAddr iop_base)
8485{
8486 PortAddr eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
8487 (PortAddr) (ASC_EISA_CFG_IOP_MASK);
8488 return inpw(eisa_cfg_iop);
8489}
8490
8491
8492
8493
8494
8495static unsigned short AscGetChipBiosAddress(PortAddr iop_base,
8496 unsigned short bus_type)
8497{
8498 unsigned short cfg_lsw;
8499 unsigned short bios_addr;
8500
8501
8502
8503
8504
8505
8506 if (bus_type & ASC_IS_PCI)
8507 return 0;
8508
8509 if ((bus_type & ASC_IS_EISA) != 0) {
8510 cfg_lsw = AscGetEisaChipCfg(iop_base);
8511 cfg_lsw &= 0x000F;
8512 bios_addr = ASC_BIOS_MIN_ADDR + cfg_lsw * ASC_BIOS_BANK_SIZE;
8513 return bios_addr;
8514 }
8515
8516 cfg_lsw = AscGetChipCfgLsw(iop_base);
8517 bios_addr = ASC_BIOS_MIN_ADDR + (cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE;
8518 return bios_addr;
8519}
8520
8521static uchar AscSetChipScsiID(PortAddr iop_base, uchar new_host_id)
8522{
8523 ushort cfg_lsw;
8524
8525 if (AscGetChipScsiID(iop_base) == new_host_id) {
8526 return (new_host_id);
8527 }
8528 cfg_lsw = AscGetChipCfgLsw(iop_base);
8529 cfg_lsw &= 0xF8FF;
8530 cfg_lsw |= (ushort)((new_host_id & ASC_MAX_TID) << 8);
8531 AscSetChipCfgLsw(iop_base, cfg_lsw);
8532 return (AscGetChipScsiID(iop_base));
8533}
8534
8535static unsigned char AscGetChipScsiCtrl(PortAddr iop_base)
8536{
8537 unsigned char sc;
8538
8539 AscSetBank(iop_base, 1);
8540 sc = inp(iop_base + IOP_REG_SC);
8541 AscSetBank(iop_base, 0);
8542 return sc;
8543}
8544
8545static unsigned char AscGetChipVersion(PortAddr iop_base,
8546 unsigned short bus_type)
8547{
8548 if (bus_type & ASC_IS_EISA) {
8549 PortAddr eisa_iop;
8550 unsigned char revision;
8551 eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
8552 (PortAddr) ASC_EISA_REV_IOP_MASK;
8553 revision = inp(eisa_iop);
8554 return ASC_CHIP_MIN_VER_EISA - 1 + revision;
8555 }
8556 return AscGetChipVerNo(iop_base);
8557}
8558
8559static int AscStopQueueExe(PortAddr iop_base)
8560{
8561 int count = 0;
8562
8563 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
8564 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
8565 ASC_STOP_REQ_RISC_STOP);
8566 do {
8567 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
8568 ASC_STOP_ACK_RISC_STOP) {
8569 return (1);
8570 }
8571 mdelay(100);
8572 } while (count++ < 20);
8573 }
8574 return (0);
8575}
8576
8577static unsigned int AscGetMaxDmaCount(ushort bus_type)
8578{
8579 if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
8580 return ASC_MAX_VL_DMA_COUNT;
8581 return ASC_MAX_PCI_DMA_COUNT;
8582}
8583
8584static void AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc)
8585{
8586 int i;
8587 PortAddr iop_base;
8588 uchar chip_version;
8589
8590 iop_base = asc_dvc->iop_base;
8591 asc_dvc->err_code = 0;
8592 if ((asc_dvc->bus_type &
8593 (ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
8594 asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
8595 }
8596 AscSetChipControl(iop_base, CC_HALT);
8597 AscSetChipStatus(iop_base, 0);
8598 asc_dvc->bug_fix_cntl = 0;
8599 asc_dvc->pci_fix_asyn_xfer = 0;
8600 asc_dvc->pci_fix_asyn_xfer_always = 0;
8601
8602 asc_dvc->sdtr_done = 0;
8603 asc_dvc->cur_total_qng = 0;
8604 asc_dvc->is_in_int = false;
8605 asc_dvc->in_critical_cnt = 0;
8606 asc_dvc->last_q_shortage = 0;
8607 asc_dvc->use_tagged_qng = 0;
8608 asc_dvc->no_scam = 0;
8609 asc_dvc->unit_not_ready = 0;
8610 asc_dvc->queue_full_or_busy = 0;
8611 asc_dvc->redo_scam = 0;
8612 asc_dvc->res2 = 0;
8613 asc_dvc->min_sdtr_index = 0;
8614 asc_dvc->cfg->can_tagged_qng = 0;
8615 asc_dvc->cfg->cmd_qng_enabled = 0;
8616 asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
8617 asc_dvc->init_sdtr = 0;
8618 asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
8619 asc_dvc->scsi_reset_wait = 3;
8620 asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
8621 asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
8622 asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
8623 asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
8624 asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
8625 chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
8626 asc_dvc->cfg->chip_version = chip_version;
8627 asc_dvc->sdtr_period_tbl = asc_syn_xfer_period;
8628 asc_dvc->max_sdtr_index = 7;
8629 if ((asc_dvc->bus_type & ASC_IS_PCI) &&
8630 (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
8631 asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
8632 asc_dvc->sdtr_period_tbl = asc_syn_ultra_xfer_period;
8633 asc_dvc->max_sdtr_index = 15;
8634 if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) {
8635 AscSetExtraControl(iop_base,
8636 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
8637 } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
8638 AscSetExtraControl(iop_base,
8639 (SEC_ACTIVE_NEGATE |
8640 SEC_ENABLE_FILTER));
8641 }
8642 }
8643 if (asc_dvc->bus_type == ASC_IS_PCI) {
8644 AscSetExtraControl(iop_base,
8645 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
8646 }
8647
8648 for (i = 0; i <= ASC_MAX_TID; i++) {
8649 asc_dvc->cur_dvc_qng[i] = 0;
8650 asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
8651 asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *)0L;
8652 asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *)0L;
8653 asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
8654 }
8655}
8656
8657static int AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg)
8658{
8659 int retry;
8660
8661 for (retry = 0; retry < ASC_EEP_MAX_RETRY; retry++) {
8662 unsigned char read_back;
8663 AscSetChipEEPCmd(iop_base, cmd_reg);
8664 mdelay(1);
8665 read_back = AscGetChipEEPCmd(iop_base);
8666 if (read_back == cmd_reg)
8667 return 1;
8668 }
8669 return 0;
8670}
8671
8672static void AscWaitEEPRead(void)
8673{
8674 mdelay(1);
8675}
8676
8677static ushort AscReadEEPWord(PortAddr iop_base, uchar addr)
8678{
8679 ushort read_wval;
8680 uchar cmd_reg;
8681
8682 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
8683 AscWaitEEPRead();
8684 cmd_reg = addr | ASC_EEP_CMD_READ;
8685 AscWriteEEPCmdReg(iop_base, cmd_reg);
8686 AscWaitEEPRead();
8687 read_wval = AscGetChipEEPData(iop_base);
8688 AscWaitEEPRead();
8689 return read_wval;
8690}
8691
8692static ushort AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf,
8693 ushort bus_type)
8694{
8695 ushort wval;
8696 ushort sum;
8697 ushort *wbuf;
8698 int cfg_beg;
8699 int cfg_end;
8700 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
8701 int s_addr;
8702
8703 wbuf = (ushort *)cfg_buf;
8704 sum = 0;
8705
8706 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
8707 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
8708 sum += *wbuf;
8709 }
8710 if (bus_type & ASC_IS_VL) {
8711 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
8712 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
8713 } else {
8714 cfg_beg = ASC_EEP_DVC_CFG_BEG;
8715 cfg_end = ASC_EEP_MAX_DVC_ADDR;
8716 }
8717 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
8718 wval = AscReadEEPWord(iop_base, (uchar)s_addr);
8719 if (s_addr <= uchar_end_in_config) {
8720
8721
8722
8723
8724 *wbuf = le16_to_cpu(wval);
8725 } else {
8726
8727 *wbuf = wval;
8728 }
8729 sum += wval;
8730 }
8731
8732
8733
8734
8735 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
8736 return sum;
8737}
8738
8739static int AscTestExternalLram(ASC_DVC_VAR *asc_dvc)
8740{
8741 PortAddr iop_base;
8742 ushort q_addr;
8743 ushort saved_word;
8744 int sta;
8745
8746 iop_base = asc_dvc->iop_base;
8747 sta = 0;
8748 q_addr = ASC_QNO_TO_QADDR(241);
8749 saved_word = AscReadLramWord(iop_base, q_addr);
8750 AscSetChipLramAddr(iop_base, q_addr);
8751 AscSetChipLramData(iop_base, 0x55AA);
8752 mdelay(10);
8753 AscSetChipLramAddr(iop_base, q_addr);
8754 if (AscGetChipLramData(iop_base) == 0x55AA) {
8755 sta = 1;
8756 AscWriteLramWord(iop_base, q_addr, saved_word);
8757 }
8758 return (sta);
8759}
8760
8761static void AscWaitEEPWrite(void)
8762{
8763 mdelay(20);
8764}
8765
8766static int AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg)
8767{
8768 ushort read_back;
8769 int retry;
8770
8771 retry = 0;
8772 while (true) {
8773 AscSetChipEEPData(iop_base, data_reg);
8774 mdelay(1);
8775 read_back = AscGetChipEEPData(iop_base);
8776 if (read_back == data_reg) {
8777 return (1);
8778 }
8779 if (retry++ > ASC_EEP_MAX_RETRY) {
8780 return (0);
8781 }
8782 }
8783}
8784
8785static ushort AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val)
8786{
8787 ushort read_wval;
8788
8789 read_wval = AscReadEEPWord(iop_base, addr);
8790 if (read_wval != word_val) {
8791 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
8792 AscWaitEEPRead();
8793 AscWriteEEPDataReg(iop_base, word_val);
8794 AscWaitEEPRead();
8795 AscWriteEEPCmdReg(iop_base,
8796 (uchar)((uchar)ASC_EEP_CMD_WRITE | addr));
8797 AscWaitEEPWrite();
8798 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
8799 AscWaitEEPRead();
8800 return (AscReadEEPWord(iop_base, addr));
8801 }
8802 return (read_wval);
8803}
8804
8805static int AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf,
8806 ushort bus_type)
8807{
8808 int n_error;
8809 ushort *wbuf;
8810 ushort word;
8811 ushort sum;
8812 int s_addr;
8813 int cfg_beg;
8814 int cfg_end;
8815 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
8816
8817 wbuf = (ushort *)cfg_buf;
8818 n_error = 0;
8819 sum = 0;
8820
8821 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
8822 sum += *wbuf;
8823 if (*wbuf != AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
8824 n_error++;
8825 }
8826 }
8827 if (bus_type & ASC_IS_VL) {
8828 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
8829 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
8830 } else {
8831 cfg_beg = ASC_EEP_DVC_CFG_BEG;
8832 cfg_end = ASC_EEP_MAX_DVC_ADDR;
8833 }
8834 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
8835 if (s_addr <= uchar_end_in_config) {
8836
8837
8838
8839
8840 word = cpu_to_le16(*wbuf);
8841 if (word !=
8842 AscWriteEEPWord(iop_base, (uchar)s_addr, word)) {
8843 n_error++;
8844 }
8845 } else {
8846
8847 if (*wbuf !=
8848 AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
8849 n_error++;
8850 }
8851 }
8852 sum += *wbuf;
8853 }
8854
8855 *wbuf = sum;
8856 if (sum != AscWriteEEPWord(iop_base, (uchar)s_addr, sum)) {
8857 n_error++;
8858 }
8859
8860
8861 wbuf = (ushort *)cfg_buf;
8862
8863
8864
8865 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
8866 if (*wbuf != AscReadEEPWord(iop_base, (uchar)s_addr)) {
8867 n_error++;
8868 }
8869 }
8870 if (bus_type & ASC_IS_VL) {
8871 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
8872 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
8873 } else {
8874 cfg_beg = ASC_EEP_DVC_CFG_BEG;
8875 cfg_end = ASC_EEP_MAX_DVC_ADDR;
8876 }
8877 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
8878 if (s_addr <= uchar_end_in_config) {
8879
8880
8881
8882
8883 word =
8884 le16_to_cpu(AscReadEEPWord
8885 (iop_base, (uchar)s_addr));
8886 } else {
8887
8888 word = AscReadEEPWord(iop_base, (uchar)s_addr);
8889 }
8890 if (*wbuf != word) {
8891 n_error++;
8892 }
8893 }
8894
8895 if (AscReadEEPWord(iop_base, (uchar)s_addr) != sum) {
8896 n_error++;
8897 }
8898 return n_error;
8899}
8900
8901static int AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf,
8902 ushort bus_type)
8903{
8904 int retry;
8905 int n_error;
8906
8907 retry = 0;
8908 while (true) {
8909 if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
8910 bus_type)) == 0) {
8911 break;
8912 }
8913 if (++retry > ASC_EEP_MAX_RETRY) {
8914 break;
8915 }
8916 }
8917 return n_error;
8918}
8919
8920static int AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
8921{
8922 ASCEEP_CONFIG eep_config_buf;
8923 ASCEEP_CONFIG *eep_config;
8924 PortAddr iop_base;
8925 ushort chksum;
8926 ushort warn_code;
8927 ushort cfg_msw, cfg_lsw;
8928 int i;
8929 int write_eep = 0;
8930
8931 iop_base = asc_dvc->iop_base;
8932 warn_code = 0;
8933 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
8934 AscStopQueueExe(iop_base);
8935 if ((AscStopChip(iop_base)) ||
8936 (AscGetChipScsiCtrl(iop_base) != 0)) {
8937 asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
8938 AscResetChipAndScsiBus(asc_dvc);
8939 mdelay(asc_dvc->scsi_reset_wait * 1000);
8940 }
8941 if (!AscIsChipHalted(iop_base)) {
8942 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
8943 return (warn_code);
8944 }
8945 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
8946 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
8947 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
8948 return (warn_code);
8949 }
8950 eep_config = (ASCEEP_CONFIG *)&eep_config_buf;
8951 cfg_msw = AscGetChipCfgMsw(iop_base);
8952 cfg_lsw = AscGetChipCfgLsw(iop_base);
8953 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
8954 cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
8955 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
8956 AscSetChipCfgMsw(iop_base, cfg_msw);
8957 }
8958 chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
8959 ASC_DBG(1, "chksum 0x%x\n", chksum);
8960 if (chksum == 0) {
8961 chksum = 0xaa55;
8962 }
8963 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
8964 warn_code |= ASC_WARN_AUTO_CONFIG;
8965 if (asc_dvc->cfg->chip_version == 3) {
8966 if (eep_config->cfg_lsw != cfg_lsw) {
8967 warn_code |= ASC_WARN_EEPROM_RECOVER;
8968 eep_config->cfg_lsw =
8969 AscGetChipCfgLsw(iop_base);
8970 }
8971 if (eep_config->cfg_msw != cfg_msw) {
8972 warn_code |= ASC_WARN_EEPROM_RECOVER;
8973 eep_config->cfg_msw =
8974 AscGetChipCfgMsw(iop_base);
8975 }
8976 }
8977 }
8978 eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
8979 eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
8980 ASC_DBG(1, "eep_config->chksum 0x%x\n", eep_config->chksum);
8981 if (chksum != eep_config->chksum) {
8982 if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
8983 ASC_CHIP_VER_PCI_ULTRA_3050) {
8984 ASC_DBG(1, "chksum error ignored; EEPROM-less board\n");
8985 eep_config->init_sdtr = 0xFF;
8986 eep_config->disc_enable = 0xFF;
8987 eep_config->start_motor = 0xFF;
8988 eep_config->use_cmd_qng = 0;
8989 eep_config->max_total_qng = 0xF0;
8990 eep_config->max_tag_qng = 0x20;
8991 eep_config->cntl = 0xBFFF;
8992 ASC_EEP_SET_CHIP_ID(eep_config, 7);
8993 eep_config->no_scam = 0;
8994 eep_config->adapter_info[0] = 0;
8995 eep_config->adapter_info[1] = 0;
8996 eep_config->adapter_info[2] = 0;
8997 eep_config->adapter_info[3] = 0;
8998 eep_config->adapter_info[4] = 0;
8999
9000 eep_config->adapter_info[5] = 0xBB;
9001 } else {
9002 ASC_PRINT
9003 ("AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
9004 write_eep = 1;
9005 warn_code |= ASC_WARN_EEPROM_CHKSUM;
9006 }
9007 }
9008 asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
9009 asc_dvc->cfg->disc_enable = eep_config->disc_enable;
9010 asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
9011 asc_dvc->start_motor = eep_config->start_motor;
9012 asc_dvc->dvc_cntl = eep_config->cntl;
9013 asc_dvc->no_scam = eep_config->no_scam;
9014 asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
9015 asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
9016 asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
9017 asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
9018 asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
9019 asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
9020 if (!AscTestExternalLram(asc_dvc)) {
9021 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) ==
9022 ASC_IS_PCI_ULTRA)) {
9023 eep_config->max_total_qng =
9024 ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
9025 eep_config->max_tag_qng =
9026 ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
9027 } else {
9028 eep_config->cfg_msw |= 0x0800;
9029 cfg_msw |= 0x0800;
9030 AscSetChipCfgMsw(iop_base, cfg_msw);
9031 eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
9032 eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
9033 }
9034 } else {
9035 }
9036 if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
9037 eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
9038 }
9039 if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
9040 eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
9041 }
9042 if (eep_config->max_tag_qng > eep_config->max_total_qng) {
9043 eep_config->max_tag_qng = eep_config->max_total_qng;
9044 }
9045 if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
9046 eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
9047 }
9048 asc_dvc->max_total_qng = eep_config->max_total_qng;
9049 if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
9050 eep_config->use_cmd_qng) {
9051 eep_config->disc_enable = eep_config->use_cmd_qng;
9052 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
9053 }
9054 ASC_EEP_SET_CHIP_ID(eep_config,
9055 ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
9056 asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
9057 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
9058 !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
9059 asc_dvc->min_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
9060 }
9061
9062 for (i = 0; i <= ASC_MAX_TID; i++) {
9063 asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
9064 asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
9065 asc_dvc->cfg->sdtr_period_offset[i] =
9066 (uchar)(ASC_DEF_SDTR_OFFSET |
9067 (asc_dvc->min_sdtr_index << 4));
9068 }
9069 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
9070 if (write_eep) {
9071 if ((i = AscSetEEPConfig(iop_base, eep_config,
9072 asc_dvc->bus_type)) != 0) {
9073 ASC_PRINT1
9074 ("AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n",
9075 i);
9076 } else {
9077 ASC_PRINT
9078 ("AscInitFromEEP: Successfully re-wrote EEPROM.\n");
9079 }
9080 }
9081 return (warn_code);
9082}
9083
9084static int AscInitGetConfig(struct Scsi_Host *shost)
9085{
9086 struct asc_board *board = shost_priv(shost);
9087 ASC_DVC_VAR *asc_dvc = &board->dvc_var.asc_dvc_var;
9088 unsigned short warn_code = 0;
9089
9090 asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
9091 if (asc_dvc->err_code != 0)
9092 return asc_dvc->err_code;
9093
9094 if (AscFindSignature(asc_dvc->iop_base)) {
9095 AscInitAscDvcVar(asc_dvc);
9096 warn_code = AscInitFromEEP(asc_dvc);
9097 asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
9098 if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT)
9099 asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
9100 } else {
9101 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
9102 }
9103
9104 switch (warn_code) {
9105 case 0:
9106 break;
9107 case ASC_WARN_IO_PORT_ROTATE:
9108 shost_printk(KERN_WARNING, shost, "I/O port address "
9109 "modified\n");
9110 break;
9111 case ASC_WARN_AUTO_CONFIG:
9112 shost_printk(KERN_WARNING, shost, "I/O port increment switch "
9113 "enabled\n");
9114 break;
9115 case ASC_WARN_EEPROM_CHKSUM:
9116 shost_printk(KERN_WARNING, shost, "EEPROM checksum error\n");
9117 break;
9118 case ASC_WARN_IRQ_MODIFIED:
9119 shost_printk(KERN_WARNING, shost, "IRQ modified\n");
9120 break;
9121 case ASC_WARN_CMD_QNG_CONFLICT:
9122 shost_printk(KERN_WARNING, shost, "tag queuing enabled w/o "
9123 "disconnects\n");
9124 break;
9125 default:
9126 shost_printk(KERN_WARNING, shost, "unknown warning: 0x%x\n",
9127 warn_code);
9128 break;
9129 }
9130
9131 if (asc_dvc->err_code != 0)
9132 shost_printk(KERN_ERR, shost, "error 0x%x at init_state "
9133 "0x%x\n", asc_dvc->err_code, asc_dvc->init_state);
9134
9135 return asc_dvc->err_code;
9136}
9137
9138static int AscInitSetConfig(struct pci_dev *pdev, struct Scsi_Host *shost)
9139{
9140 struct asc_board *board = shost_priv(shost);
9141 ASC_DVC_VAR *asc_dvc = &board->dvc_var.asc_dvc_var;
9142 PortAddr iop_base = asc_dvc->iop_base;
9143 unsigned short cfg_msw;
9144 unsigned short warn_code = 0;
9145
9146 asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
9147 if (asc_dvc->err_code != 0)
9148 return asc_dvc->err_code;
9149 if (!AscFindSignature(asc_dvc->iop_base)) {
9150 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
9151 return asc_dvc->err_code;
9152 }
9153
9154 cfg_msw = AscGetChipCfgMsw(iop_base);
9155 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
9156 cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
9157 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
9158 AscSetChipCfgMsw(iop_base, cfg_msw);
9159 }
9160 if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
9161 asc_dvc->cfg->cmd_qng_enabled) {
9162 asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
9163 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
9164 }
9165 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
9166 warn_code |= ASC_WARN_AUTO_CONFIG;
9167 }
9168#ifdef CONFIG_PCI
9169 if (asc_dvc->bus_type & ASC_IS_PCI) {
9170 cfg_msw &= 0xFFC0;
9171 AscSetChipCfgMsw(iop_base, cfg_msw);
9172 if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
9173 } else {
9174 if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
9175 (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
9176 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
9177 asc_dvc->bug_fix_cntl |=
9178 ASC_BUG_FIX_ASYN_USE_SYN;
9179 }
9180 }
9181 } else
9182#endif
9183 if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
9184 asc_dvc->cfg->chip_scsi_id) {
9185 asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
9186 }
9187
9188 asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
9189
9190 switch (warn_code) {
9191 case 0:
9192 break;
9193 case ASC_WARN_IO_PORT_ROTATE:
9194 shost_printk(KERN_WARNING, shost, "I/O port address "
9195 "modified\n");
9196 break;
9197 case ASC_WARN_AUTO_CONFIG:
9198 shost_printk(KERN_WARNING, shost, "I/O port increment switch "
9199 "enabled\n");
9200 break;
9201 case ASC_WARN_EEPROM_CHKSUM:
9202 shost_printk(KERN_WARNING, shost, "EEPROM checksum error\n");
9203 break;
9204 case ASC_WARN_IRQ_MODIFIED:
9205 shost_printk(KERN_WARNING, shost, "IRQ modified\n");
9206 break;
9207 case ASC_WARN_CMD_QNG_CONFLICT:
9208 shost_printk(KERN_WARNING, shost, "tag queuing w/o "
9209 "disconnects\n");
9210 break;
9211 default:
9212 shost_printk(KERN_WARNING, shost, "unknown warning: 0x%x\n",
9213 warn_code);
9214 break;
9215 }
9216
9217 if (asc_dvc->err_code != 0)
9218 shost_printk(KERN_ERR, shost, "error 0x%x at init_state "
9219 "0x%x\n", asc_dvc->err_code, asc_dvc->init_state);
9220
9221 return asc_dvc->err_code;
9222}
9223
9224
9225
9226
9227
9228
9229
9230
9231
9232
9233
9234
9235
9236
9237
9238
9239
9240#ifdef CONFIG_PCI
9241static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config = {
9242 ADV_EEPROM_BIOS_ENABLE,
9243 0x0000,
9244 0xFFFF,
9245 0xFFFF,
9246 0xFFFF,
9247 0xFFFF,
9248 0xFFFF,
9249 0xFFFF,
9250 0,
9251 7,
9252 0,
9253 3,
9254 0,
9255 0,
9256 0,
9257 0xFFE7,
9258 0xFFFF,
9259 0,
9260 ASC_DEF_MAX_HOST_QNG,
9261 ASC_DEF_MAX_DVC_QNG,
9262 0,
9263 0,
9264 0,
9265 0,
9266 0,
9267 0,
9268 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
9269 ,
9270 0,
9271 0,
9272 0,
9273 0,
9274 0,
9275 0,
9276 0
9277};
9278
9279static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar = {
9280 0,
9281 0,
9282 0,
9283 0,
9284 0,
9285 0,
9286 0,
9287 0,
9288 0,
9289 1,
9290 1,
9291 1,
9292 1,
9293 1,
9294 1,
9295 0,
9296 0,
9297 0,
9298 1,
9299 1,
9300 0,
9301 0,
9302 0,
9303 0,
9304 0,
9305 0,
9306 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
9307 ,
9308 0,
9309 0,
9310 0,
9311 0,
9312 0,
9313 0,
9314 0
9315};
9316
9317static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config = {
9318 ADV_EEPROM_BIOS_ENABLE,
9319 0x0000,
9320 0xFFFF,
9321 0xFFFF,
9322 0x4444,
9323 0xFFFF,
9324 0xFFFF,
9325 0xFFFF,
9326 0,
9327 7,
9328 0,
9329 3,
9330 0,
9331 0,
9332 0,
9333 0xFFE7,
9334 0x4444,
9335 0x4444,
9336 ASC_DEF_MAX_HOST_QNG,
9337 ASC_DEF_MAX_DVC_QNG,
9338 0,
9339 0x4444,
9340 0,
9341 0,
9342 0,
9343 0,
9344 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
9345 ,
9346 0,
9347 0,
9348 0,
9349 0,
9350 0,
9351 0,
9352 0,
9353 0,
9354 0,
9355 0,
9356 0,
9357 0,
9358 0,
9359 0,
9360 0,
9361 0,
9362 0,
9363 0,
9364 0,
9365 0,
9366 0,
9367 0,
9368 0,
9369 0,
9370 0,
9371 0,
9372 0,
9373 0,
9374 PCI_VENDOR_ID_ASP,
9375 PCI_DEVICE_ID_38C0800_REV1,
9376 0,
9377 0,
9378 0,
9379 0
9380};
9381
9382static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar = {
9383 0,
9384 0,
9385 0,
9386 0,
9387 0,
9388 0,
9389 0,
9390 0,
9391 0,
9392 1,
9393 1,
9394 1,
9395 1,
9396 1,
9397 1,
9398 0,
9399 0,
9400 0,
9401 1,
9402 1,
9403 0,
9404 0,
9405 0,
9406 0,
9407 0,
9408 0,
9409 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
9410 ,
9411 0,
9412 0,
9413 0,
9414 0,
9415 0,
9416 0,
9417 0,
9418 0,
9419 0,
9420 0,
9421 0,
9422 0,
9423 0,
9424 0,
9425 0,
9426 0,
9427 0,
9428 0,
9429 0,
9430 0,
9431 0,
9432 0,
9433 0,
9434 0,
9435 0,
9436 0,
9437 0,
9438 0,
9439 0,
9440 0,
9441 0,
9442 0,
9443 0,
9444 0
9445};
9446
9447static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config = {
9448 ADV_EEPROM_BIOS_ENABLE,
9449 0x0000,
9450 0xFFFF,
9451 0xFFFF,
9452 0x5555,
9453 0xFFFF,
9454 0xFFFF,
9455 0xFFFF,
9456 0,
9457 7,
9458 0,
9459 3,
9460 0,
9461 0,
9462 0,
9463 0xFFE7,
9464 0x5555,
9465 0x5555,
9466 ASC_DEF_MAX_HOST_QNG,
9467 ASC_DEF_MAX_DVC_QNG,
9468 0,
9469 0x5555,
9470 0,
9471 0,
9472 0,
9473 0,
9474 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
9475 ,
9476 0,
9477 0,
9478 0,
9479 0,
9480 0,
9481 0,
9482 0,
9483 0,
9484 0,
9485 0,
9486 0,
9487 0,
9488 0,
9489 0,
9490 0,
9491 0,
9492 0,
9493 0,
9494 0,
9495 0,
9496 0,
9497 0,
9498 0,
9499 0,
9500 0,
9501 0,
9502 0,
9503 0,
9504 PCI_VENDOR_ID_ASP,
9505 PCI_DEVICE_ID_38C1600_REV1,
9506 0,
9507 0,
9508 0,
9509 0
9510};
9511
9512static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar = {
9513 0,
9514 0,
9515 0,
9516 0,
9517 0,
9518 0,
9519 0,
9520 0,
9521 0,
9522 1,
9523 1,
9524 1,
9525 1,
9526 1,
9527 1,
9528 0,
9529 0,
9530 0,
9531 1,
9532 1,
9533 0,
9534 0,
9535 0,
9536 0,
9537 0,
9538 0,
9539 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
9540 ,
9541 0,
9542 0,
9543 0,
9544 0,
9545 0,
9546 0,
9547 0,
9548 0,
9549 0,
9550 0,
9551 0,
9552 0,
9553 0,
9554 0,
9555 0,
9556 0,
9557 0,
9558 0,
9559 0,
9560 0,
9561 0,
9562 0,
9563 0,
9564 0,
9565 0,
9566 0,
9567 0,
9568 0,
9569 0,
9570 0,
9571 0,
9572 0,
9573 0,
9574 0
9575};
9576
9577
9578
9579
9580static void AdvWaitEEPCmd(AdvPortAddr iop_base)
9581{
9582 int eep_delay_ms;
9583
9584 for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++) {
9585 if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) &
9586 ASC_EEP_CMD_DONE) {
9587 break;
9588 }
9589 mdelay(1);
9590 }
9591 if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) ==
9592 0)
9593 BUG();
9594}
9595
9596
9597
9598
9599static ushort AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
9600{
9601 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
9602 ASC_EEP_CMD_READ | eep_word_addr);
9603 AdvWaitEEPCmd(iop_base);
9604 return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
9605}
9606
9607
9608
9609
9610static void AdvSet3550EEPConfig(AdvPortAddr iop_base,
9611 ADVEEP_3550_CONFIG *cfg_buf)
9612{
9613 ushort *wbuf;
9614 ushort addr, chksum;
9615 ushort *charfields;
9616
9617 wbuf = (ushort *)cfg_buf;
9618 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
9619 chksum = 0;
9620
9621 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
9622 AdvWaitEEPCmd(iop_base);
9623
9624
9625
9626
9627 for (addr = ADV_EEP_DVC_CFG_BEGIN;
9628 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
9629 ushort word;
9630
9631 if (*charfields++) {
9632 word = cpu_to_le16(*wbuf);
9633 } else {
9634 word = *wbuf;
9635 }
9636 chksum += *wbuf;
9637 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
9638 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
9639 ASC_EEP_CMD_WRITE | addr);
9640 AdvWaitEEPCmd(iop_base);
9641 mdelay(ADV_EEP_DELAY_MS);
9642 }
9643
9644
9645
9646
9647 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
9648 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
9649 AdvWaitEEPCmd(iop_base);
9650 wbuf++;
9651 charfields++;
9652
9653
9654
9655
9656 for (addr = ADV_EEP_DVC_CTL_BEGIN;
9657 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
9658 ushort word;
9659
9660 if (*charfields++) {
9661 word = cpu_to_le16(*wbuf);
9662 } else {
9663 word = *wbuf;
9664 }
9665 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
9666 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
9667 ASC_EEP_CMD_WRITE | addr);
9668 AdvWaitEEPCmd(iop_base);
9669 }
9670 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
9671 AdvWaitEEPCmd(iop_base);
9672}
9673
9674
9675
9676
9677static void AdvSet38C0800EEPConfig(AdvPortAddr iop_base,
9678 ADVEEP_38C0800_CONFIG *cfg_buf)
9679{
9680 ushort *wbuf;
9681 ushort *charfields;
9682 ushort addr, chksum;
9683
9684 wbuf = (ushort *)cfg_buf;
9685 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
9686 chksum = 0;
9687
9688 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
9689 AdvWaitEEPCmd(iop_base);
9690
9691
9692
9693
9694 for (addr = ADV_EEP_DVC_CFG_BEGIN;
9695 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
9696 ushort word;
9697
9698 if (*charfields++) {
9699 word = cpu_to_le16(*wbuf);
9700 } else {
9701 word = *wbuf;
9702 }
9703 chksum += *wbuf;
9704 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
9705 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
9706 ASC_EEP_CMD_WRITE | addr);
9707 AdvWaitEEPCmd(iop_base);
9708 mdelay(ADV_EEP_DELAY_MS);
9709 }
9710
9711
9712
9713
9714 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
9715 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
9716 AdvWaitEEPCmd(iop_base);
9717 wbuf++;
9718 charfields++;
9719
9720
9721
9722
9723 for (addr = ADV_EEP_DVC_CTL_BEGIN;
9724 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
9725 ushort word;
9726
9727 if (*charfields++) {
9728 word = cpu_to_le16(*wbuf);
9729 } else {
9730 word = *wbuf;
9731 }
9732 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
9733 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
9734 ASC_EEP_CMD_WRITE | addr);
9735 AdvWaitEEPCmd(iop_base);
9736 }
9737 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
9738 AdvWaitEEPCmd(iop_base);
9739}
9740
9741
9742
9743
9744static void AdvSet38C1600EEPConfig(AdvPortAddr iop_base,
9745 ADVEEP_38C1600_CONFIG *cfg_buf)
9746{
9747 ushort *wbuf;
9748 ushort *charfields;
9749 ushort addr, chksum;
9750
9751 wbuf = (ushort *)cfg_buf;
9752 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
9753 chksum = 0;
9754
9755 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
9756 AdvWaitEEPCmd(iop_base);
9757
9758
9759
9760
9761 for (addr = ADV_EEP_DVC_CFG_BEGIN;
9762 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
9763 ushort word;
9764
9765 if (*charfields++) {
9766 word = cpu_to_le16(*wbuf);
9767 } else {
9768 word = *wbuf;
9769 }
9770 chksum += *wbuf;
9771 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
9772 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
9773 ASC_EEP_CMD_WRITE | addr);
9774 AdvWaitEEPCmd(iop_base);
9775 mdelay(ADV_EEP_DELAY_MS);
9776 }
9777
9778
9779
9780
9781 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
9782 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
9783 AdvWaitEEPCmd(iop_base);
9784 wbuf++;
9785 charfields++;
9786
9787
9788
9789
9790 for (addr = ADV_EEP_DVC_CTL_BEGIN;
9791 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
9792 ushort word;
9793
9794 if (*charfields++) {
9795 word = cpu_to_le16(*wbuf);
9796 } else {
9797 word = *wbuf;
9798 }
9799 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
9800 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
9801 ASC_EEP_CMD_WRITE | addr);
9802 AdvWaitEEPCmd(iop_base);
9803 }
9804 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
9805 AdvWaitEEPCmd(iop_base);
9806}
9807
9808
9809
9810
9811
9812
9813static ushort AdvGet3550EEPConfig(AdvPortAddr iop_base,
9814 ADVEEP_3550_CONFIG *cfg_buf)
9815{
9816 ushort wval, chksum;
9817 ushort *wbuf;
9818 int eep_addr;
9819 ushort *charfields;
9820
9821 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
9822 wbuf = (ushort *)cfg_buf;
9823 chksum = 0;
9824
9825 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
9826 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
9827 wval = AdvReadEEPWord(iop_base, eep_addr);
9828 chksum += wval;
9829 if (*charfields++) {
9830 *wbuf = le16_to_cpu(wval);
9831 } else {
9832 *wbuf = wval;
9833 }
9834 }
9835
9836 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
9837 wbuf++;
9838 charfields++;
9839
9840
9841 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
9842 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
9843 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
9844 if (*charfields++) {
9845 *wbuf = le16_to_cpu(*wbuf);
9846 }
9847 }
9848 return chksum;
9849}
9850
9851
9852
9853
9854
9855
9856static ushort AdvGet38C0800EEPConfig(AdvPortAddr iop_base,
9857 ADVEEP_38C0800_CONFIG *cfg_buf)
9858{
9859 ushort wval, chksum;
9860 ushort *wbuf;
9861 int eep_addr;
9862 ushort *charfields;
9863
9864 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
9865 wbuf = (ushort *)cfg_buf;
9866 chksum = 0;
9867
9868 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
9869 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
9870 wval = AdvReadEEPWord(iop_base, eep_addr);
9871 chksum += wval;
9872 if (*charfields++) {
9873 *wbuf = le16_to_cpu(wval);
9874 } else {
9875 *wbuf = wval;
9876 }
9877 }
9878
9879 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
9880 wbuf++;
9881 charfields++;
9882
9883
9884 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
9885 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
9886 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
9887 if (*charfields++) {
9888 *wbuf = le16_to_cpu(*wbuf);
9889 }
9890 }
9891 return chksum;
9892}
9893
9894
9895
9896
9897
9898
9899static ushort AdvGet38C1600EEPConfig(AdvPortAddr iop_base,
9900 ADVEEP_38C1600_CONFIG *cfg_buf)
9901{
9902 ushort wval, chksum;
9903 ushort *wbuf;
9904 int eep_addr;
9905 ushort *charfields;
9906
9907 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
9908 wbuf = (ushort *)cfg_buf;
9909 chksum = 0;
9910
9911 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
9912 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
9913 wval = AdvReadEEPWord(iop_base, eep_addr);
9914 chksum += wval;
9915 if (*charfields++) {
9916 *wbuf = le16_to_cpu(wval);
9917 } else {
9918 *wbuf = wval;
9919 }
9920 }
9921
9922 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
9923 wbuf++;
9924 charfields++;
9925
9926
9927 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
9928 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
9929 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
9930 if (*charfields++) {
9931 *wbuf = le16_to_cpu(*wbuf);
9932 }
9933 }
9934 return chksum;
9935}
9936
9937
9938
9939
9940
9941
9942
9943
9944
9945
9946
9947
9948
9949static int AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
9950{
9951 AdvPortAddr iop_base;
9952 ushort warn_code;
9953 ADVEEP_3550_CONFIG eep_config;
9954
9955 iop_base = asc_dvc->iop_base;
9956
9957 warn_code = 0;
9958
9959
9960
9961
9962
9963
9964 if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum) {
9965 warn_code |= ASC_WARN_EEPROM_CHKSUM;
9966
9967
9968
9969
9970 memcpy(&eep_config, &Default_3550_EEPROM_Config,
9971 sizeof(ADVEEP_3550_CONFIG));
9972
9973
9974
9975
9976
9977 eep_config.serial_number_word3 =
9978 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
9979
9980 eep_config.serial_number_word2 =
9981 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
9982
9983 eep_config.serial_number_word1 =
9984 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
9985
9986 AdvSet3550EEPConfig(iop_base, &eep_config);
9987 }
9988
9989
9990
9991
9992
9993
9994 asc_dvc->wdtr_able = eep_config.wdtr_able;
9995 asc_dvc->sdtr_able = eep_config.sdtr_able;
9996 asc_dvc->ultra_able = eep_config.ultra_able;
9997 asc_dvc->tagqng_able = eep_config.tagqng_able;
9998 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
9999 asc_dvc->max_host_qng = eep_config.max_host_qng;
10000 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
10001 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
10002 asc_dvc->start_motor = eep_config.start_motor;
10003 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
10004 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
10005 asc_dvc->no_scam = eep_config.scam_tolerant;
10006 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
10007 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
10008 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
10009
10010
10011
10012
10013
10014 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
10015 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
10016 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
10017
10018 if (eep_config.max_host_qng == 0) {
10019 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
10020 } else {
10021 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
10022 }
10023 }
10024
10025 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
10026 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
10027 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
10028
10029 if (eep_config.max_dvc_qng == 0) {
10030 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
10031 } else {
10032 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
10033 }
10034 }
10035
10036
10037
10038
10039
10040 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
10041 eep_config.max_dvc_qng = eep_config.max_host_qng;
10042 }
10043
10044
10045
10046
10047
10048 asc_dvc->max_host_qng = eep_config.max_host_qng;
10049 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
10050
10051
10052
10053
10054
10055
10056
10057
10058
10059 if (eep_config.termination == 0) {
10060 asc_dvc->cfg->termination = 0;
10061 } else {
10062
10063 if (eep_config.termination == 1) {
10064 asc_dvc->cfg->termination = TERM_CTL_SEL;
10065
10066
10067 } else if (eep_config.termination == 2) {
10068 asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
10069
10070
10071 } else if (eep_config.termination == 3) {
10072 asc_dvc->cfg->termination =
10073 TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
10074 } else {
10075
10076
10077
10078
10079 asc_dvc->cfg->termination = 0;
10080 warn_code |= ASC_WARN_EEPROM_TERMINATION;
10081 }
10082 }
10083
10084 return warn_code;
10085}
10086
10087
10088
10089
10090
10091
10092
10093
10094
10095
10096
10097
10098
10099static int AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
10100{
10101 AdvPortAddr iop_base;
10102 ushort warn_code;
10103 ADVEEP_38C0800_CONFIG eep_config;
10104 uchar tid, termination;
10105 ushort sdtr_speed = 0;
10106
10107 iop_base = asc_dvc->iop_base;
10108
10109 warn_code = 0;
10110
10111
10112
10113
10114
10115
10116 if (AdvGet38C0800EEPConfig(iop_base, &eep_config) !=
10117 eep_config.check_sum) {
10118 warn_code |= ASC_WARN_EEPROM_CHKSUM;
10119
10120
10121
10122
10123 memcpy(&eep_config, &Default_38C0800_EEPROM_Config,
10124 sizeof(ADVEEP_38C0800_CONFIG));
10125
10126
10127
10128
10129
10130 eep_config.serial_number_word3 =
10131 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
10132
10133 eep_config.serial_number_word2 =
10134 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
10135
10136 eep_config.serial_number_word1 =
10137 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
10138
10139 AdvSet38C0800EEPConfig(iop_base, &eep_config);
10140 }
10141
10142
10143
10144
10145
10146
10147 asc_dvc->wdtr_able = eep_config.wdtr_able;
10148 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
10149 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
10150 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
10151 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
10152 asc_dvc->tagqng_able = eep_config.tagqng_able;
10153 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
10154 asc_dvc->max_host_qng = eep_config.max_host_qng;
10155 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
10156 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
10157 asc_dvc->start_motor = eep_config.start_motor;
10158 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
10159 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
10160 asc_dvc->no_scam = eep_config.scam_tolerant;
10161 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
10162 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
10163 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
10164
10165
10166
10167
10168
10169 asc_dvc->sdtr_able = 0;
10170 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
10171 if (tid == 0) {
10172 sdtr_speed = asc_dvc->sdtr_speed1;
10173 } else if (tid == 4) {
10174 sdtr_speed = asc_dvc->sdtr_speed2;
10175 } else if (tid == 8) {
10176 sdtr_speed = asc_dvc->sdtr_speed3;
10177 } else if (tid == 12) {
10178 sdtr_speed = asc_dvc->sdtr_speed4;
10179 }
10180 if (sdtr_speed & ADV_MAX_TID) {
10181 asc_dvc->sdtr_able |= (1 << tid);
10182 }
10183 sdtr_speed >>= 4;
10184 }
10185
10186
10187
10188
10189
10190 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
10191 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
10192 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
10193
10194 if (eep_config.max_host_qng == 0) {
10195 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
10196 } else {
10197 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
10198 }
10199 }
10200
10201 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
10202 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
10203 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
10204
10205 if (eep_config.max_dvc_qng == 0) {
10206 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
10207 } else {
10208 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
10209 }
10210 }
10211
10212
10213
10214
10215
10216 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
10217 eep_config.max_dvc_qng = eep_config.max_host_qng;
10218 }
10219
10220
10221
10222
10223
10224 asc_dvc->max_host_qng = eep_config.max_host_qng;
10225 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
10226
10227
10228
10229
10230
10231
10232
10233
10234
10235 if (eep_config.termination_se == 0) {
10236 termination = 0;
10237 } else {
10238
10239 if (eep_config.termination_se == 1) {
10240 termination = 0;
10241
10242
10243 } else if (eep_config.termination_se == 2) {
10244 termination = TERM_SE_HI;
10245
10246
10247 } else if (eep_config.termination_se == 3) {
10248 termination = TERM_SE;
10249 } else {
10250
10251
10252
10253
10254 termination = 0;
10255 warn_code |= ASC_WARN_EEPROM_TERMINATION;
10256 }
10257 }
10258
10259 if (eep_config.termination_lvd == 0) {
10260 asc_dvc->cfg->termination = termination;
10261 } else {
10262
10263 if (eep_config.termination_lvd == 1) {
10264 asc_dvc->cfg->termination = termination;
10265
10266
10267 } else if (eep_config.termination_lvd == 2) {
10268 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
10269
10270
10271 } else if (eep_config.termination_lvd == 3) {
10272 asc_dvc->cfg->termination = termination | TERM_LVD;
10273 } else {
10274
10275
10276
10277
10278 asc_dvc->cfg->termination = termination;
10279 warn_code |= ASC_WARN_EEPROM_TERMINATION;
10280 }
10281 }
10282
10283 return warn_code;
10284}
10285
10286
10287
10288
10289
10290
10291
10292
10293
10294
10295
10296
10297
10298static int AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
10299{
10300 AdvPortAddr iop_base;
10301 ushort warn_code;
10302 ADVEEP_38C1600_CONFIG eep_config;
10303 uchar tid, termination;
10304 ushort sdtr_speed = 0;
10305
10306 iop_base = asc_dvc->iop_base;
10307
10308 warn_code = 0;
10309
10310
10311
10312
10313
10314
10315 if (AdvGet38C1600EEPConfig(iop_base, &eep_config) !=
10316 eep_config.check_sum) {
10317 struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc);
10318 warn_code |= ASC_WARN_EEPROM_CHKSUM;
10319
10320
10321
10322
10323 memcpy(&eep_config, &Default_38C1600_EEPROM_Config,
10324 sizeof(ADVEEP_38C1600_CONFIG));
10325
10326 if (PCI_FUNC(pdev->devfn) != 0) {
10327 u8 ints;
10328
10329
10330
10331
10332
10333 eep_config.cfg_lsw &= ~ADV_EEPROM_BIOS_ENABLE;
10334
10335
10336
10337
10338
10339
10340
10341
10342
10343
10344
10345
10346
10347 AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL, 0);
10348 ints = AdvReadByteRegister(iop_base, IOPB_GPIO_DATA);
10349 if ((ints & 0x01) == 0)
10350 eep_config.cfg_lsw &= ~ADV_EEPROM_INTAB;
10351 }
10352
10353
10354
10355
10356
10357 eep_config.serial_number_word3 =
10358 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
10359 eep_config.serial_number_word2 =
10360 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
10361 eep_config.serial_number_word1 =
10362 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
10363
10364 AdvSet38C1600EEPConfig(iop_base, &eep_config);
10365 }
10366
10367
10368
10369
10370
10371
10372
10373 asc_dvc->wdtr_able = eep_config.wdtr_able;
10374 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
10375 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
10376 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
10377 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
10378 asc_dvc->ppr_able = 0;
10379 asc_dvc->tagqng_able = eep_config.tagqng_able;
10380 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
10381 asc_dvc->max_host_qng = eep_config.max_host_qng;
10382 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
10383 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
10384 asc_dvc->start_motor = eep_config.start_motor;
10385 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
10386 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
10387 asc_dvc->no_scam = eep_config.scam_tolerant;
10388
10389
10390
10391
10392
10393 asc_dvc->sdtr_able = 0;
10394 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
10395 if (tid == 0) {
10396 sdtr_speed = asc_dvc->sdtr_speed1;
10397 } else if (tid == 4) {
10398 sdtr_speed = asc_dvc->sdtr_speed2;
10399 } else if (tid == 8) {
10400 sdtr_speed = asc_dvc->sdtr_speed3;
10401 } else if (tid == 12) {
10402 sdtr_speed = asc_dvc->sdtr_speed4;
10403 }
10404 if (sdtr_speed & ASC_MAX_TID) {
10405 asc_dvc->sdtr_able |= (1 << tid);
10406 }
10407 sdtr_speed >>= 4;
10408 }
10409
10410
10411
10412
10413
10414 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
10415 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
10416 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
10417
10418 if (eep_config.max_host_qng == 0) {
10419 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
10420 } else {
10421 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
10422 }
10423 }
10424
10425 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
10426 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
10427 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
10428
10429 if (eep_config.max_dvc_qng == 0) {
10430 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
10431 } else {
10432 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
10433 }
10434 }
10435
10436
10437
10438
10439
10440 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
10441 eep_config.max_dvc_qng = eep_config.max_host_qng;
10442 }
10443
10444
10445
10446
10447
10448 asc_dvc->max_host_qng = eep_config.max_host_qng;
10449 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
10450
10451
10452
10453
10454
10455
10456
10457
10458
10459 if (eep_config.termination_se == 0) {
10460 termination = 0;
10461 } else {
10462
10463 if (eep_config.termination_se == 1) {
10464 termination = 0;
10465
10466
10467 } else if (eep_config.termination_se == 2) {
10468 termination = TERM_SE_HI;
10469
10470
10471 } else if (eep_config.termination_se == 3) {
10472 termination = TERM_SE;
10473 } else {
10474
10475
10476
10477
10478 termination = 0;
10479 warn_code |= ASC_WARN_EEPROM_TERMINATION;
10480 }
10481 }
10482
10483 if (eep_config.termination_lvd == 0) {
10484 asc_dvc->cfg->termination = termination;
10485 } else {
10486
10487 if (eep_config.termination_lvd == 1) {
10488 asc_dvc->cfg->termination = termination;
10489
10490
10491 } else if (eep_config.termination_lvd == 2) {
10492 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
10493
10494
10495 } else if (eep_config.termination_lvd == 3) {
10496 asc_dvc->cfg->termination = termination | TERM_LVD;
10497 } else {
10498
10499
10500
10501
10502 asc_dvc->cfg->termination = termination;
10503 warn_code |= ASC_WARN_EEPROM_TERMINATION;
10504 }
10505 }
10506
10507 return warn_code;
10508}
10509
10510
10511
10512
10513
10514
10515
10516
10517
10518static int AdvInitGetConfig(struct pci_dev *pdev, struct Scsi_Host *shost)
10519{
10520 struct asc_board *board = shost_priv(shost);
10521 ADV_DVC_VAR *asc_dvc = &board->dvc_var.adv_dvc_var;
10522 unsigned short warn_code = 0;
10523 AdvPortAddr iop_base = asc_dvc->iop_base;
10524 u16 cmd;
10525 int status;
10526
10527 asc_dvc->err_code = 0;
10528
10529
10530
10531
10532
10533
10534
10535 asc_dvc->cfg->control_flag = 0;
10536 pci_read_config_word(pdev, PCI_COMMAND, &cmd);
10537 if ((cmd & PCI_COMMAND_PARITY) == 0)
10538 asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
10539
10540 asc_dvc->cfg->chip_version =
10541 AdvGetChipVersion(iop_base, asc_dvc->bus_type);
10542
10543 ASC_DBG(1, "iopb_chip_id_1: 0x%x 0x%x\n",
10544 (ushort)AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
10545 (ushort)ADV_CHIP_ID_BYTE);
10546
10547 ASC_DBG(1, "iopw_chip_id_0: 0x%x 0x%x\n",
10548 (ushort)AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
10549 (ushort)ADV_CHIP_ID_WORD);
10550
10551
10552
10553
10554 if (AdvFindSignature(iop_base) == 0) {
10555 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10556 return ADV_ERROR;
10557 } else {
10558
10559
10560
10561 if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
10562 asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
10563 asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
10564 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
10565 return ADV_ERROR;
10566 }
10567
10568
10569
10570
10571 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
10572 ADV_CTRL_REG_CMD_RESET);
10573 mdelay(100);
10574 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
10575 ADV_CTRL_REG_CMD_WR_IO_REG);
10576
10577 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
10578 status = AdvInitFrom38C1600EEP(asc_dvc);
10579 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
10580 status = AdvInitFrom38C0800EEP(asc_dvc);
10581 } else {
10582 status = AdvInitFrom3550EEP(asc_dvc);
10583 }
10584 warn_code |= status;
10585 }
10586
10587 if (warn_code != 0)
10588 shost_printk(KERN_WARNING, shost, "warning: 0x%x\n", warn_code);
10589
10590 if (asc_dvc->err_code)
10591 shost_printk(KERN_ERR, shost, "error code 0x%x\n",
10592 asc_dvc->err_code);
10593
10594 return asc_dvc->err_code;
10595}
10596#endif
10597
10598static struct scsi_host_template advansys_template = {
10599 .proc_name = DRV_NAME,
10600#ifdef CONFIG_PROC_FS
10601 .show_info = advansys_show_info,
10602#endif
10603 .name = DRV_NAME,
10604 .info = advansys_info,
10605 .queuecommand = advansys_queuecommand,
10606 .eh_host_reset_handler = advansys_reset,
10607 .bios_param = advansys_biosparam,
10608 .slave_configure = advansys_slave_configure,
10609};
10610
10611static int advansys_wide_init_chip(struct Scsi_Host *shost)
10612{
10613 struct asc_board *board = shost_priv(shost);
10614 struct adv_dvc_var *adv_dvc = &board->dvc_var.adv_dvc_var;
10615 size_t sgblk_pool_size;
10616 int warn_code, err_code;
10617
10618
10619
10620
10621
10622 adv_dvc->carrier = dma_alloc_coherent(board->dev,
10623 ADV_CARRIER_BUFSIZE, &adv_dvc->carrier_addr, GFP_KERNEL);
10624 ASC_DBG(1, "carrier 0x%p\n", adv_dvc->carrier);
10625
10626 if (!adv_dvc->carrier)
10627 goto kmalloc_failed;
10628
10629
10630
10631
10632
10633
10634 board->adv_reqp_size = adv_dvc->max_host_qng * sizeof(adv_req_t);
10635 if (board->adv_reqp_size & 0x1f) {
10636 ASC_DBG(1, "unaligned reqp %lu bytes\n", sizeof(adv_req_t));
10637 board->adv_reqp_size = ADV_32BALIGN(board->adv_reqp_size);
10638 }
10639 board->adv_reqp = dma_alloc_coherent(board->dev, board->adv_reqp_size,
10640 &board->adv_reqp_addr, GFP_KERNEL);
10641
10642 if (!board->adv_reqp)
10643 goto kmalloc_failed;
10644
10645 ASC_DBG(1, "reqp 0x%p, req_cnt %d, bytes %lu\n", board->adv_reqp,
10646 adv_dvc->max_host_qng, board->adv_reqp_size);
10647
10648
10649
10650
10651
10652 sgblk_pool_size = sizeof(adv_sgblk_t) * ADV_TOT_SG_BLOCK;
10653 board->adv_sgblk_pool = dma_pool_create("adv_sgblk", board->dev,
10654 sgblk_pool_size, 32, 0);
10655
10656 ASC_DBG(1, "sg_cnt %d * %lu = %lu bytes\n", ADV_TOT_SG_BLOCK,
10657 sizeof(adv_sgblk_t), sgblk_pool_size);
10658
10659 if (!board->adv_sgblk_pool)
10660 goto kmalloc_failed;
10661
10662 if (adv_dvc->chip_type == ADV_CHIP_ASC3550) {
10663 ASC_DBG(2, "AdvInitAsc3550Driver()\n");
10664 warn_code = AdvInitAsc3550Driver(adv_dvc);
10665 } else if (adv_dvc->chip_type == ADV_CHIP_ASC38C0800) {
10666 ASC_DBG(2, "AdvInitAsc38C0800Driver()\n");
10667 warn_code = AdvInitAsc38C0800Driver(adv_dvc);
10668 } else {
10669 ASC_DBG(2, "AdvInitAsc38C1600Driver()\n");
10670 warn_code = AdvInitAsc38C1600Driver(adv_dvc);
10671 }
10672 err_code = adv_dvc->err_code;
10673
10674 if (warn_code || err_code) {
10675 shost_printk(KERN_WARNING, shost, "error: warn 0x%x, error "
10676 "0x%x\n", warn_code, err_code);
10677 }
10678
10679 goto exit;
10680
10681 kmalloc_failed:
10682 shost_printk(KERN_ERR, shost, "error: kmalloc() failed\n");
10683 err_code = ADV_ERROR;
10684 exit:
10685 return err_code;
10686}
10687
10688static void advansys_wide_free_mem(struct asc_board *board)
10689{
10690 struct adv_dvc_var *adv_dvc = &board->dvc_var.adv_dvc_var;
10691
10692 if (adv_dvc->carrier) {
10693 dma_free_coherent(board->dev, ADV_CARRIER_BUFSIZE,
10694 adv_dvc->carrier, adv_dvc->carrier_addr);
10695 adv_dvc->carrier = NULL;
10696 }
10697 if (board->adv_reqp) {
10698 dma_free_coherent(board->dev, board->adv_reqp_size,
10699 board->adv_reqp, board->adv_reqp_addr);
10700 board->adv_reqp = NULL;
10701 }
10702 if (board->adv_sgblk_pool) {
10703 dma_pool_destroy(board->adv_sgblk_pool);
10704 board->adv_sgblk_pool = NULL;
10705 }
10706}
10707
10708static int advansys_board_found(struct Scsi_Host *shost, unsigned int iop,
10709 int bus_type)
10710{
10711 struct pci_dev *pdev;
10712 struct asc_board *boardp = shost_priv(shost);
10713 ASC_DVC_VAR *asc_dvc_varp = NULL;
10714 ADV_DVC_VAR *adv_dvc_varp = NULL;
10715 int share_irq, warn_code, ret;
10716
10717 pdev = (bus_type == ASC_IS_PCI) ? to_pci_dev(boardp->dev) : NULL;
10718
10719 if (ASC_NARROW_BOARD(boardp)) {
10720 ASC_DBG(1, "narrow board\n");
10721 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
10722 asc_dvc_varp->bus_type = bus_type;
10723 asc_dvc_varp->drv_ptr = boardp;
10724 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
10725 asc_dvc_varp->iop_base = iop;
10726 } else {
10727#ifdef CONFIG_PCI
10728 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
10729 adv_dvc_varp->drv_ptr = boardp;
10730 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
10731 if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) {
10732 ASC_DBG(1, "wide board ASC-3550\n");
10733 adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
10734 } else if (pdev->device == PCI_DEVICE_ID_38C0800_REV1) {
10735 ASC_DBG(1, "wide board ASC-38C0800\n");
10736 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
10737 } else {
10738 ASC_DBG(1, "wide board ASC-38C1600\n");
10739 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
10740 }
10741
10742 boardp->asc_n_io_port = pci_resource_len(pdev, 1);
10743 boardp->ioremap_addr = pci_ioremap_bar(pdev, 1);
10744 if (!boardp->ioremap_addr) {
10745 shost_printk(KERN_ERR, shost, "ioremap(%lx, %d) "
10746 "returned NULL\n",
10747 (long)pci_resource_start(pdev, 1),
10748 boardp->asc_n_io_port);
10749 ret = -ENODEV;
10750 goto err_shost;
10751 }
10752 adv_dvc_varp->iop_base = (AdvPortAddr)boardp->ioremap_addr;
10753 ASC_DBG(1, "iop_base: 0x%p\n", adv_dvc_varp->iop_base);
10754
10755
10756
10757
10758
10759
10760 boardp->ioport = iop;
10761
10762 ASC_DBG(1, "iopb_chip_id_1 0x%x, iopw_chip_id_0 0x%x\n",
10763 (ushort)inp(iop + 1), (ushort)inpw(iop));
10764#endif
10765 }
10766
10767 if (ASC_NARROW_BOARD(boardp)) {
10768
10769
10770
10771
10772 switch (asc_dvc_varp->bus_type) {
10773#ifdef CONFIG_ISA
10774 case ASC_IS_VL:
10775 share_irq = 0;
10776 break;
10777 case ASC_IS_EISA:
10778 share_irq = IRQF_SHARED;
10779 break;
10780#endif
10781#ifdef CONFIG_PCI
10782 case ASC_IS_PCI:
10783 share_irq = IRQF_SHARED;
10784 break;
10785#endif
10786 default:
10787 shost_printk(KERN_ERR, shost, "unknown adapter type: "
10788 "%d\n", asc_dvc_varp->bus_type);
10789 share_irq = 0;
10790 break;
10791 }
10792
10793
10794
10795
10796
10797
10798
10799 ASC_DBG(2, "AscInitGetConfig()\n");
10800 ret = AscInitGetConfig(shost) ? -ENODEV : 0;
10801 } else {
10802#ifdef CONFIG_PCI
10803
10804
10805
10806
10807 share_irq = IRQF_SHARED;
10808 ASC_DBG(2, "AdvInitGetConfig()\n");
10809
10810 ret = AdvInitGetConfig(pdev, shost) ? -ENODEV : 0;
10811#else
10812 share_irq = 0;
10813 ret = -ENODEV;
10814#endif
10815 }
10816
10817 if (ret)
10818 goto err_unmap;
10819
10820
10821
10822
10823
10824 if (ASC_NARROW_BOARD(boardp)) {
10825
10826 ASCEEP_CONFIG *ep;
10827
10828
10829
10830
10831 boardp->init_tidmask |=
10832 ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
10833
10834
10835
10836
10837 ep = &boardp->eep_config.asc_eep;
10838
10839 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
10840 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
10841 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
10842 ASC_EEP_SET_DMA_SPD(ep, ASC_DEF_ISA_DMA_SPEED);
10843 ep->start_motor = asc_dvc_varp->start_motor;
10844 ep->cntl = asc_dvc_varp->dvc_cntl;
10845 ep->no_scam = asc_dvc_varp->no_scam;
10846 ep->max_total_qng = asc_dvc_varp->max_total_qng;
10847 ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
10848
10849 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
10850 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
10851 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
10852 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
10853 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
10854 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
10855 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
10856
10857
10858
10859
10860 ASC_DBG(2, "AscInitSetConfig()\n");
10861 ret = AscInitSetConfig(pdev, shost) ? -ENODEV : 0;
10862 if (ret)
10863 goto err_unmap;
10864 } else {
10865 ADVEEP_3550_CONFIG *ep_3550;
10866 ADVEEP_38C0800_CONFIG *ep_38C0800;
10867 ADVEEP_38C1600_CONFIG *ep_38C1600;
10868
10869
10870
10871
10872 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
10873 ep_3550 = &boardp->eep_config.adv_3550_eep;
10874
10875 ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
10876 ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
10877 ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
10878 ep_3550->termination = adv_dvc_varp->cfg->termination;
10879 ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
10880 ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
10881 ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
10882 ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
10883 ep_3550->ultra_able = adv_dvc_varp->ultra_able;
10884 ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
10885 ep_3550->start_motor = adv_dvc_varp->start_motor;
10886 ep_3550->scsi_reset_delay =
10887 adv_dvc_varp->scsi_reset_wait;
10888 ep_3550->serial_number_word1 =
10889 adv_dvc_varp->cfg->serial1;
10890 ep_3550->serial_number_word2 =
10891 adv_dvc_varp->cfg->serial2;
10892 ep_3550->serial_number_word3 =
10893 adv_dvc_varp->cfg->serial3;
10894 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
10895 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
10896
10897 ep_38C0800->adapter_scsi_id =
10898 adv_dvc_varp->chip_scsi_id;
10899 ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
10900 ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
10901 ep_38C0800->termination_lvd =
10902 adv_dvc_varp->cfg->termination;
10903 ep_38C0800->disc_enable =
10904 adv_dvc_varp->cfg->disc_enable;
10905 ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
10906 ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
10907 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
10908 ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
10909 ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
10910 ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
10911 ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
10912 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
10913 ep_38C0800->start_motor = adv_dvc_varp->start_motor;
10914 ep_38C0800->scsi_reset_delay =
10915 adv_dvc_varp->scsi_reset_wait;
10916 ep_38C0800->serial_number_word1 =
10917 adv_dvc_varp->cfg->serial1;
10918 ep_38C0800->serial_number_word2 =
10919 adv_dvc_varp->cfg->serial2;
10920 ep_38C0800->serial_number_word3 =
10921 adv_dvc_varp->cfg->serial3;
10922 } else {
10923 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
10924
10925 ep_38C1600->adapter_scsi_id =
10926 adv_dvc_varp->chip_scsi_id;
10927 ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
10928 ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
10929 ep_38C1600->termination_lvd =
10930 adv_dvc_varp->cfg->termination;
10931 ep_38C1600->disc_enable =
10932 adv_dvc_varp->cfg->disc_enable;
10933 ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
10934 ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
10935 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
10936 ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
10937 ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
10938 ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
10939 ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
10940 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
10941 ep_38C1600->start_motor = adv_dvc_varp->start_motor;
10942 ep_38C1600->scsi_reset_delay =
10943 adv_dvc_varp->scsi_reset_wait;
10944 ep_38C1600->serial_number_word1 =
10945 adv_dvc_varp->cfg->serial1;
10946 ep_38C1600->serial_number_word2 =
10947 adv_dvc_varp->cfg->serial2;
10948 ep_38C1600->serial_number_word3 =
10949 adv_dvc_varp->cfg->serial3;
10950 }
10951
10952
10953
10954
10955 boardp->init_tidmask |=
10956 ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
10957 }
10958
10959
10960
10961
10962
10963
10964 shost->max_channel = 0;
10965 if (ASC_NARROW_BOARD(boardp)) {
10966 shost->max_id = ASC_MAX_TID + 1;
10967 shost->max_lun = ASC_MAX_LUN + 1;
10968 shost->max_cmd_len = ASC_MAX_CDB_LEN;
10969
10970 shost->io_port = asc_dvc_varp->iop_base;
10971 boardp->asc_n_io_port = ASC_IOADR_GAP;
10972 shost->this_id = asc_dvc_varp->cfg->chip_scsi_id;
10973
10974
10975 shost->can_queue = asc_dvc_varp->max_total_qng;
10976 } else {
10977 shost->max_id = ADV_MAX_TID + 1;
10978 shost->max_lun = ADV_MAX_LUN + 1;
10979 shost->max_cmd_len = ADV_MAX_CDB_LEN;
10980
10981
10982
10983
10984
10985
10986
10987 shost->io_port = iop;
10988
10989 shost->this_id = adv_dvc_varp->chip_scsi_id;
10990
10991
10992 shost->can_queue = adv_dvc_varp->max_host_qng;
10993 }
10994
10995
10996
10997
10998
10999 if (ASC_NARROW_BOARD(boardp)) {
11000
11001
11002
11003
11004
11005
11006 shost->sg_tablesize =
11007 (((asc_dvc_varp->max_total_qng - 2) / 2) *
11008 ASC_SG_LIST_PER_Q) + 1;
11009 } else {
11010 shost->sg_tablesize = ADV_MAX_SG_LIST;
11011 }
11012
11013
11014
11015
11016
11017
11018
11019 if (shost->sg_tablesize > SG_ALL) {
11020 shost->sg_tablesize = SG_ALL;
11021 }
11022
11023 ASC_DBG(1, "sg_tablesize: %d\n", shost->sg_tablesize);
11024
11025
11026 if (ASC_NARROW_BOARD(boardp)) {
11027 shost->base = AscGetChipBiosAddress(asc_dvc_varp->iop_base,
11028 asc_dvc_varp->bus_type);
11029 } else {
11030
11031
11032
11033
11034 AdvReadWordLram(adv_dvc_varp->iop_base,
11035 BIOS_SIGNATURE, boardp->bios_signature);
11036 AdvReadWordLram(adv_dvc_varp->iop_base,
11037 BIOS_VERSION, boardp->bios_version);
11038 AdvReadWordLram(adv_dvc_varp->iop_base,
11039 BIOS_CODESEG, boardp->bios_codeseg);
11040 AdvReadWordLram(adv_dvc_varp->iop_base,
11041 BIOS_CODELEN, boardp->bios_codelen);
11042
11043 ASC_DBG(1, "bios_signature 0x%x, bios_version 0x%x\n",
11044 boardp->bios_signature, boardp->bios_version);
11045
11046 ASC_DBG(1, "bios_codeseg 0x%x, bios_codelen 0x%x\n",
11047 boardp->bios_codeseg, boardp->bios_codelen);
11048
11049
11050
11051
11052
11053 if (boardp->bios_signature == 0x55AA) {
11054
11055
11056
11057
11058 shost->base = ((ulong)boardp->bios_codeseg << 4);
11059 } else {
11060 shost->base = 0;
11061 }
11062 }
11063
11064
11065
11066
11067
11068
11069 shost->dma_channel = NO_ISA_DMA;
11070
11071
11072 ASC_DBG(2, "request_irq(%d, %p)\n", boardp->irq, shost);
11073
11074 ret = request_irq(boardp->irq, advansys_interrupt, share_irq,
11075 DRV_NAME, shost);
11076
11077 if (ret) {
11078 if (ret == -EBUSY) {
11079 shost_printk(KERN_ERR, shost, "request_irq(): IRQ 0x%x "
11080 "already in use\n", boardp->irq);
11081 } else if (ret == -EINVAL) {
11082 shost_printk(KERN_ERR, shost, "request_irq(): IRQ 0x%x "
11083 "not valid\n", boardp->irq);
11084 } else {
11085 shost_printk(KERN_ERR, shost, "request_irq(): IRQ 0x%x "
11086 "failed with %d\n", boardp->irq, ret);
11087 }
11088 goto err_unmap;
11089 }
11090
11091
11092
11093
11094 if (ASC_NARROW_BOARD(boardp)) {
11095 ASC_DBG(2, "AscInitAsc1000Driver()\n");
11096
11097 asc_dvc_varp->overrun_buf = kzalloc(ASC_OVERRUN_BSIZE, GFP_KERNEL);
11098 if (!asc_dvc_varp->overrun_buf) {
11099 ret = -ENOMEM;
11100 goto err_free_irq;
11101 }
11102 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
11103
11104 if (warn_code || asc_dvc_varp->err_code) {
11105 shost_printk(KERN_ERR, shost, "error: init_state 0x%x, "
11106 "warn 0x%x, error 0x%x\n",
11107 asc_dvc_varp->init_state, warn_code,
11108 asc_dvc_varp->err_code);
11109 if (!asc_dvc_varp->overrun_dma) {
11110 ret = -ENODEV;
11111 goto err_free_mem;
11112 }
11113 }
11114 } else {
11115 if (advansys_wide_init_chip(shost)) {
11116 ret = -ENODEV;
11117 goto err_free_mem;
11118 }
11119 }
11120
11121 ASC_DBG_PRT_SCSI_HOST(2, shost);
11122
11123 ret = scsi_add_host(shost, boardp->dev);
11124 if (ret)
11125 goto err_free_mem;
11126
11127 scsi_scan_host(shost);
11128 return 0;
11129
11130 err_free_mem:
11131 if (ASC_NARROW_BOARD(boardp)) {
11132 if (asc_dvc_varp->overrun_dma)
11133 dma_unmap_single(boardp->dev, asc_dvc_varp->overrun_dma,
11134 ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE);
11135 kfree(asc_dvc_varp->overrun_buf);
11136 } else
11137 advansys_wide_free_mem(boardp);
11138 err_free_irq:
11139 free_irq(boardp->irq, shost);
11140 err_unmap:
11141 if (boardp->ioremap_addr)
11142 iounmap(boardp->ioremap_addr);
11143#ifdef CONFIG_PCI
11144 err_shost:
11145#endif
11146 return ret;
11147}
11148
11149
11150
11151
11152
11153
11154static int advansys_release(struct Scsi_Host *shost)
11155{
11156 struct asc_board *board = shost_priv(shost);
11157 ASC_DBG(1, "begin\n");
11158 scsi_remove_host(shost);
11159 free_irq(board->irq, shost);
11160
11161 if (ASC_NARROW_BOARD(board)) {
11162 dma_unmap_single(board->dev,
11163 board->dvc_var.asc_dvc_var.overrun_dma,
11164 ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE);
11165 kfree(board->dvc_var.asc_dvc_var.overrun_buf);
11166 } else {
11167 iounmap(board->ioremap_addr);
11168 advansys_wide_free_mem(board);
11169 }
11170 scsi_host_put(shost);
11171 ASC_DBG(1, "end\n");
11172 return 0;
11173}
11174
11175#define ASC_IOADR_TABLE_MAX_IX 11
11176
11177static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] = {
11178 0x100, 0x0110, 0x120, 0x0130, 0x140, 0x0150, 0x0190,
11179 0x0210, 0x0230, 0x0250, 0x0330
11180};
11181
11182static void advansys_vlb_remove(struct device *dev, unsigned int id)
11183{
11184 int ioport = _asc_def_iop_base[id];
11185 advansys_release(dev_get_drvdata(dev));
11186 release_region(ioport, ASC_IOADR_GAP);
11187}
11188
11189
11190
11191
11192
11193
11194
11195
11196
11197
11198
11199
11200static unsigned int advansys_vlb_irq_no(PortAddr iop_base)
11201{
11202 unsigned short cfg_lsw = AscGetChipCfgLsw(iop_base);
11203 unsigned int chip_irq = ((cfg_lsw >> 2) & 0x07) + 9;
11204 if ((chip_irq < 10) || (chip_irq == 13) || (chip_irq > 15))
11205 return 0;
11206 return chip_irq;
11207}
11208
11209static int advansys_vlb_probe(struct device *dev, unsigned int id)
11210{
11211 int err = -ENODEV;
11212 PortAddr iop_base = _asc_def_iop_base[id];
11213 struct Scsi_Host *shost;
11214 struct asc_board *board;
11215
11216 if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) {
11217 ASC_DBG(1, "I/O port 0x%x busy\n", iop_base);
11218 return -ENODEV;
11219 }
11220 ASC_DBG(1, "probing I/O port 0x%x\n", iop_base);
11221 if (!AscFindSignature(iop_base))
11222 goto release_region;
11223
11224
11225
11226
11227
11228 if (AscGetChipVersion(iop_base, ASC_IS_VL) > ASC_CHIP_MAX_VER_VL)
11229 goto release_region;
11230
11231 err = -ENOMEM;
11232 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
11233 if (!shost)
11234 goto release_region;
11235
11236 board = shost_priv(shost);
11237 board->irq = advansys_vlb_irq_no(iop_base);
11238 board->dev = dev;
11239 board->shost = shost;
11240
11241 err = advansys_board_found(shost, iop_base, ASC_IS_VL);
11242 if (err)
11243 goto free_host;
11244
11245 dev_set_drvdata(dev, shost);
11246 return 0;
11247
11248 free_host:
11249 scsi_host_put(shost);
11250 release_region:
11251 release_region(iop_base, ASC_IOADR_GAP);
11252 return -ENODEV;
11253}
11254
11255static struct isa_driver advansys_vlb_driver = {
11256 .probe = advansys_vlb_probe,
11257 .remove = advansys_vlb_remove,
11258 .driver = {
11259 .owner = THIS_MODULE,
11260 .name = "advansys_vlb",
11261 },
11262};
11263
11264static struct eisa_device_id advansys_eisa_table[] = {
11265 { "ABP7401" },
11266 { "ABP7501" },
11267 { "" }
11268};
11269
11270MODULE_DEVICE_TABLE(eisa, advansys_eisa_table);
11271
11272
11273
11274
11275
11276struct eisa_scsi_data {
11277 struct Scsi_Host *host[2];
11278};
11279
11280
11281
11282
11283
11284
11285
11286
11287
11288
11289
11290
11291static unsigned int advansys_eisa_irq_no(struct eisa_device *edev)
11292{
11293 unsigned short cfg_lsw = inw(edev->base_addr + 0xc86);
11294 unsigned int chip_irq = ((cfg_lsw >> 8) & 0x07) + 10;
11295 if ((chip_irq == 13) || (chip_irq > 15))
11296 return 0;
11297 return chip_irq;
11298}
11299
11300static int advansys_eisa_probe(struct device *dev)
11301{
11302 int i, ioport, irq = 0;
11303 int err;
11304 struct eisa_device *edev = to_eisa_device(dev);
11305 struct eisa_scsi_data *data;
11306
11307 err = -ENOMEM;
11308 data = kzalloc(sizeof(*data), GFP_KERNEL);
11309 if (!data)
11310 goto fail;
11311 ioport = edev->base_addr + 0xc30;
11312
11313 err = -ENODEV;
11314 for (i = 0; i < 2; i++, ioport += 0x20) {
11315 struct asc_board *board;
11316 struct Scsi_Host *shost;
11317 if (!request_region(ioport, ASC_IOADR_GAP, DRV_NAME)) {
11318 printk(KERN_WARNING "Region %x-%x busy\n", ioport,
11319 ioport + ASC_IOADR_GAP - 1);
11320 continue;
11321 }
11322 if (!AscFindSignature(ioport)) {
11323 release_region(ioport, ASC_IOADR_GAP);
11324 continue;
11325 }
11326
11327
11328
11329
11330
11331
11332
11333
11334 inw(ioport + 4);
11335
11336 if (!irq)
11337 irq = advansys_eisa_irq_no(edev);
11338
11339 err = -ENOMEM;
11340 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
11341 if (!shost)
11342 goto release_region;
11343
11344 board = shost_priv(shost);
11345 board->irq = irq;
11346 board->dev = dev;
11347 board->shost = shost;
11348
11349 err = advansys_board_found(shost, ioport, ASC_IS_EISA);
11350 if (!err) {
11351 data->host[i] = shost;
11352 continue;
11353 }
11354
11355 scsi_host_put(shost);
11356 release_region:
11357 release_region(ioport, ASC_IOADR_GAP);
11358 break;
11359 }
11360
11361 if (err)
11362 goto free_data;
11363 dev_set_drvdata(dev, data);
11364 return 0;
11365
11366 free_data:
11367 kfree(data->host[0]);
11368 kfree(data->host[1]);
11369 kfree(data);
11370 fail:
11371 return err;
11372}
11373
11374static int advansys_eisa_remove(struct device *dev)
11375{
11376 int i;
11377 struct eisa_scsi_data *data = dev_get_drvdata(dev);
11378
11379 for (i = 0; i < 2; i++) {
11380 int ioport;
11381 struct Scsi_Host *shost = data->host[i];
11382 if (!shost)
11383 continue;
11384 ioport = shost->io_port;
11385 advansys_release(shost);
11386 release_region(ioport, ASC_IOADR_GAP);
11387 }
11388
11389 kfree(data);
11390 return 0;
11391}
11392
11393static struct eisa_driver advansys_eisa_driver = {
11394 .id_table = advansys_eisa_table,
11395 .driver = {
11396 .name = DRV_NAME,
11397 .probe = advansys_eisa_probe,
11398 .remove = advansys_eisa_remove,
11399 }
11400};
11401
11402
11403static struct pci_device_id advansys_pci_tbl[] = {
11404 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A,
11405 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
11406 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940,
11407 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
11408 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940U,
11409 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
11410 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940UW,
11411 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
11412 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C0800_REV1,
11413 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
11414 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C1600_REV1,
11415 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
11416 {}
11417};
11418
11419MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);
11420
11421static void advansys_set_latency(struct pci_dev *pdev)
11422{
11423 if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
11424 (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
11425 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0);
11426 } else {
11427 u8 latency;
11428 pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency);
11429 if (latency < 0x20)
11430 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x20);
11431 }
11432}
11433
11434static int advansys_pci_probe(struct pci_dev *pdev,
11435 const struct pci_device_id *ent)
11436{
11437 int err, ioport;
11438 struct Scsi_Host *shost;
11439 struct asc_board *board;
11440
11441 err = pci_enable_device(pdev);
11442 if (err)
11443 goto fail;
11444 err = pci_request_regions(pdev, DRV_NAME);
11445 if (err)
11446 goto disable_device;
11447 pci_set_master(pdev);
11448 advansys_set_latency(pdev);
11449
11450 err = -ENODEV;
11451 if (pci_resource_len(pdev, 0) == 0)
11452 goto release_region;
11453
11454 ioport = pci_resource_start(pdev, 0);
11455
11456 err = -ENOMEM;
11457 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
11458 if (!shost)
11459 goto release_region;
11460
11461 board = shost_priv(shost);
11462 board->irq = pdev->irq;
11463 board->dev = &pdev->dev;
11464 board->shost = shost;
11465
11466 if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW ||
11467 pdev->device == PCI_DEVICE_ID_38C0800_REV1 ||
11468 pdev->device == PCI_DEVICE_ID_38C1600_REV1) {
11469 board->flags |= ASC_IS_WIDE_BOARD;
11470 }
11471
11472 err = advansys_board_found(shost, ioport, ASC_IS_PCI);
11473 if (err)
11474 goto free_host;
11475
11476 pci_set_drvdata(pdev, shost);
11477 return 0;
11478
11479 free_host:
11480 scsi_host_put(shost);
11481 release_region:
11482 pci_release_regions(pdev);
11483 disable_device:
11484 pci_disable_device(pdev);
11485 fail:
11486 return err;
11487}
11488
11489static void advansys_pci_remove(struct pci_dev *pdev)
11490{
11491 advansys_release(pci_get_drvdata(pdev));
11492 pci_release_regions(pdev);
11493 pci_disable_device(pdev);
11494}
11495
11496static struct pci_driver advansys_pci_driver = {
11497 .name = DRV_NAME,
11498 .id_table = advansys_pci_tbl,
11499 .probe = advansys_pci_probe,
11500 .remove = advansys_pci_remove,
11501};
11502
11503static int __init advansys_init(void)
11504{
11505 int error;
11506
11507 error = isa_register_driver(&advansys_vlb_driver,
11508 ASC_IOADR_TABLE_MAX_IX);
11509 if (error)
11510 goto fail;
11511
11512 error = eisa_driver_register(&advansys_eisa_driver);
11513 if (error)
11514 goto unregister_vlb;
11515
11516 error = pci_register_driver(&advansys_pci_driver);
11517 if (error)
11518 goto unregister_eisa;
11519
11520 return 0;
11521
11522 unregister_eisa:
11523 eisa_driver_unregister(&advansys_eisa_driver);
11524 unregister_vlb:
11525 isa_unregister_driver(&advansys_vlb_driver);
11526 fail:
11527 return error;
11528}
11529
11530static void __exit advansys_exit(void)
11531{
11532 pci_unregister_driver(&advansys_pci_driver);
11533 eisa_driver_unregister(&advansys_eisa_driver);
11534 isa_unregister_driver(&advansys_vlb_driver);
11535}
11536
11537module_init(advansys_init);
11538module_exit(advansys_exit);
11539
11540MODULE_LICENSE("GPL");
11541MODULE_FIRMWARE("advansys/mcode.bin");
11542MODULE_FIRMWARE("advansys/3550.bin");
11543MODULE_FIRMWARE("advansys/38C0800.bin");
11544MODULE_FIRMWARE("advansys/38C1600.bin");
11545