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