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