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 ASCEEP_CONFIG *ep;
2880 int i;
2881 uchar serialstr[13];
2882#ifdef CONFIG_ISA
2883 ASC_DVC_VAR *asc_dvc_varp;
2884 int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
2885
2886 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
2887#endif
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
3175 seq_printf(m,
3176 "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
3177 shost->host_no);
3178
3179 seq_printf(m,
3180 " host_busy %d, max_id %u, max_lun %llu, max_channel %u\n",
3181 scsi_host_busy(shost), shost->max_id,
3182 shost->max_lun, shost->max_channel);
3183
3184 seq_printf(m,
3185 " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
3186 shost->unique_id, shost->can_queue, shost->this_id,
3187 shost->sg_tablesize, shost->cmd_per_lun);
3188
3189 seq_printf(m,
3190 " unchecked_isa_dma %d\n",
3191 shost->unchecked_isa_dma);
3192
3193 seq_printf(m,
3194 " flags 0x%x, last_reset 0x%lx, jiffies 0x%lx, asc_n_io_port 0x%x\n",
3195 boardp->flags, shost->last_reset, jiffies,
3196 boardp->asc_n_io_port);
3197
3198 seq_printf(m, " io_port 0x%lx\n", shost->io_port);
3199}
3200
3201
3202
3203
3204
3205
3206static void asc_prt_asc_board_info(struct seq_file *m, struct Scsi_Host *shost)
3207{
3208 struct asc_board *boardp = shost_priv(shost);
3209 int chip_scsi_id;
3210 ASC_DVC_VAR *v;
3211 ASC_DVC_CFG *c;
3212 int i;
3213 int renegotiate = 0;
3214
3215 v = &boardp->dvc_var.asc_dvc_var;
3216 c = &boardp->dvc_cfg.asc_dvc_cfg;
3217 chip_scsi_id = c->chip_scsi_id;
3218
3219 seq_printf(m,
3220 "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
3221 shost->host_no);
3222
3223 seq_printf(m, " chip_version %u, mcode_date 0x%x, "
3224 "mcode_version 0x%x, err_code %u\n",
3225 c->chip_version, c->mcode_date, c->mcode_version,
3226 v->err_code);
3227
3228
3229 seq_printf(m,
3230 " Total Command Pending: %d\n", v->cur_total_qng);
3231
3232 seq_puts(m, " Command Queuing:");
3233 for (i = 0; i <= ASC_MAX_TID; i++) {
3234 if ((chip_scsi_id == i) ||
3235 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3236 continue;
3237 }
3238 seq_printf(m, " %X:%c",
3239 i,
3240 (v->use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3241 }
3242
3243
3244 seq_puts(m, "\n Command Queue Pending:");
3245 for (i = 0; i <= ASC_MAX_TID; i++) {
3246 if ((chip_scsi_id == i) ||
3247 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3248 continue;
3249 }
3250 seq_printf(m, " %X:%u", i, v->cur_dvc_qng[i]);
3251 }
3252
3253
3254 seq_puts(m, "\n Command Queue Limit:");
3255 for (i = 0; i <= ASC_MAX_TID; i++) {
3256 if ((chip_scsi_id == i) ||
3257 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3258 continue;
3259 }
3260 seq_printf(m, " %X:%u", i, v->max_dvc_qng[i]);
3261 }
3262
3263
3264 seq_puts(m, "\n Command Queue Full:");
3265 for (i = 0; i <= ASC_MAX_TID; i++) {
3266 if ((chip_scsi_id == i) ||
3267 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3268 continue;
3269 }
3270 if (boardp->queue_full & ADV_TID_TO_TIDMASK(i))
3271 seq_printf(m, " %X:Y-%d",
3272 i, boardp->queue_full_cnt[i]);
3273 else
3274 seq_printf(m, " %X:N", i);
3275 }
3276
3277 seq_puts(m, "\n Synchronous Transfer:");
3278 for (i = 0; i <= ASC_MAX_TID; i++) {
3279 if ((chip_scsi_id == i) ||
3280 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3281 continue;
3282 }
3283 seq_printf(m, " %X:%c",
3284 i,
3285 (v->sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3286 }
3287 seq_putc(m, '\n');
3288
3289 for (i = 0; i <= ASC_MAX_TID; i++) {
3290 uchar syn_period_ix;
3291
3292 if ((chip_scsi_id == i) ||
3293 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
3294 ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
3295 continue;
3296 }
3297
3298 seq_printf(m, " %X:", i);
3299
3300 if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0) {
3301 seq_puts(m, " Asynchronous");
3302 } else {
3303 syn_period_ix =
3304 (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index -
3305 1);
3306
3307 seq_printf(m,
3308 " Transfer Period Factor: %d (%d.%d Mhz),",
3309 v->sdtr_period_tbl[syn_period_ix],
3310 250 / v->sdtr_period_tbl[syn_period_ix],
3311 ASC_TENTHS(250,
3312 v->sdtr_period_tbl[syn_period_ix]));
3313
3314 seq_printf(m, " REQ/ACK Offset: %d",
3315 boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET);
3316 }
3317
3318 if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
3319 seq_puts(m, "*\n");
3320 renegotiate = 1;
3321 } else {
3322 seq_putc(m, '\n');
3323 }
3324 }
3325
3326 if (renegotiate) {
3327 seq_puts(m, " * = Re-negotiation pending before next command.\n");
3328 }
3329}
3330
3331
3332
3333
3334
3335
3336static void asc_prt_adv_board_info(struct seq_file *m, struct Scsi_Host *shost)
3337{
3338 struct asc_board *boardp = shost_priv(shost);
3339 int i;
3340 ADV_DVC_VAR *v;
3341 ADV_DVC_CFG *c;
3342 AdvPortAddr iop_base;
3343 ushort chip_scsi_id;
3344 ushort lramword;
3345 uchar lrambyte;
3346 ushort tagqng_able;
3347 ushort sdtr_able, wdtr_able;
3348 ushort wdtr_done, sdtr_done;
3349 ushort period = 0;
3350 int renegotiate = 0;
3351
3352 v = &boardp->dvc_var.adv_dvc_var;
3353 c = &boardp->dvc_cfg.adv_dvc_cfg;
3354 iop_base = v->iop_base;
3355 chip_scsi_id = v->chip_scsi_id;
3356
3357 seq_printf(m,
3358 "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
3359 shost->host_no);
3360
3361 seq_printf(m,
3362 " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
3363 (unsigned long)v->iop_base,
3364 AdvReadWordRegister(iop_base,IOPW_SCSI_CFG1) & CABLE_DETECT,
3365 v->err_code);
3366
3367 seq_printf(m, " chip_version %u, mcode_date 0x%x, "
3368 "mcode_version 0x%x\n", c->chip_version,
3369 c->mcode_date, c->mcode_version);
3370
3371 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
3372 seq_puts(m, " Queuing Enabled:");
3373 for (i = 0; i <= ADV_MAX_TID; i++) {
3374 if ((chip_scsi_id == i) ||
3375 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3376 continue;
3377 }
3378
3379 seq_printf(m, " %X:%c",
3380 i,
3381 (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3382 }
3383
3384 seq_puts(m, "\n Queue Limit:");
3385 for (i = 0; i <= ADV_MAX_TID; i++) {
3386 if ((chip_scsi_id == i) ||
3387 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3388 continue;
3389 }
3390
3391 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i,
3392 lrambyte);
3393
3394 seq_printf(m, " %X:%d", i, lrambyte);
3395 }
3396
3397 seq_puts(m, "\n Command Pending:");
3398 for (i = 0; i <= ADV_MAX_TID; i++) {
3399 if ((chip_scsi_id == i) ||
3400 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3401 continue;
3402 }
3403
3404 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i,
3405 lrambyte);
3406
3407 seq_printf(m, " %X:%d", i, lrambyte);
3408 }
3409 seq_putc(m, '\n');
3410
3411 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
3412 seq_puts(m, " Wide Enabled:");
3413 for (i = 0; i <= ADV_MAX_TID; i++) {
3414 if ((chip_scsi_id == i) ||
3415 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3416 continue;
3417 }
3418
3419 seq_printf(m, " %X:%c",
3420 i,
3421 (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3422 }
3423 seq_putc(m, '\n');
3424
3425 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
3426 seq_puts(m, " Transfer Bit Width:");
3427 for (i = 0; i <= ADV_MAX_TID; i++) {
3428 if ((chip_scsi_id == i) ||
3429 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3430 continue;
3431 }
3432
3433 AdvReadWordLram(iop_base,
3434 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
3435 lramword);
3436
3437 seq_printf(m, " %X:%d",
3438 i, (lramword & 0x8000) ? 16 : 8);
3439
3440 if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
3441 (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
3442 seq_putc(m, '*');
3443 renegotiate = 1;
3444 }
3445 }
3446 seq_putc(m, '\n');
3447
3448 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
3449 seq_puts(m, " Synchronous Enabled:");
3450 for (i = 0; i <= ADV_MAX_TID; i++) {
3451 if ((chip_scsi_id == i) ||
3452 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3453 continue;
3454 }
3455
3456 seq_printf(m, " %X:%c",
3457 i,
3458 (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3459 }
3460 seq_putc(m, '\n');
3461
3462 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
3463 for (i = 0; i <= ADV_MAX_TID; i++) {
3464
3465 AdvReadWordLram(iop_base,
3466 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
3467 lramword);
3468 lramword &= ~0x8000;
3469
3470 if ((chip_scsi_id == i) ||
3471 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
3472 ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
3473 continue;
3474 }
3475
3476 seq_printf(m, " %X:", i);
3477
3478 if ((lramword & 0x1F) == 0) {
3479 seq_puts(m, " Asynchronous");
3480 } else {
3481 seq_puts(m, " Transfer Period Factor: ");
3482
3483 if ((lramword & 0x1F00) == 0x1100) {
3484 seq_puts(m, "9 (80.0 Mhz),");
3485 } else if ((lramword & 0x1F00) == 0x1000) {
3486 seq_puts(m, "10 (40.0 Mhz),");
3487 } else {
3488
3489 period = (((lramword >> 8) * 25) + 50) / 4;
3490
3491 if (period == 0) {
3492 seq_printf(m, "%d (? Mhz), ", period);
3493 } else {
3494 seq_printf(m,
3495 "%d (%d.%d Mhz),",
3496 period, 250 / period,
3497 ASC_TENTHS(250, period));
3498 }
3499 }
3500
3501 seq_printf(m, " REQ/ACK Offset: %d",
3502 lramword & 0x1F);
3503 }
3504
3505 if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
3506 seq_puts(m, "*\n");
3507 renegotiate = 1;
3508 } else {
3509 seq_putc(m, '\n');
3510 }
3511 }
3512
3513 if (renegotiate) {
3514 seq_puts(m, " * = Re-negotiation pending before next command.\n");
3515 }
3516}
3517
3518#ifdef ADVANSYS_STATS
3519
3520
3521
3522static void asc_prt_board_stats(struct seq_file *m, struct Scsi_Host *shost)
3523{
3524 struct asc_board *boardp = shost_priv(shost);
3525 struct asc_stats *s = &boardp->asc_stats;
3526
3527 seq_printf(m,
3528 "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n",
3529 shost->host_no);
3530
3531 seq_printf(m,
3532 " queuecommand %u, reset %u, biosparam %u, interrupt %u\n",
3533 s->queuecommand, s->reset, s->biosparam,
3534 s->interrupt);
3535
3536 seq_printf(m,
3537 " callback %u, done %u, build_error %u, build_noreq %u, build_nosg %u\n",
3538 s->callback, s->done, s->build_error,
3539 s->adv_build_noreq, s->adv_build_nosg);
3540
3541 seq_printf(m,
3542 " exe_noerror %u, exe_busy %u, exe_error %u, exe_unknown %u\n",
3543 s->exe_noerror, s->exe_busy, s->exe_error,
3544 s->exe_unknown);
3545
3546
3547
3548
3549 if (s->xfer_cnt > 0) {
3550 seq_printf(m, " xfer_cnt %u, xfer_elem %u, ",
3551 s->xfer_cnt, s->xfer_elem);
3552
3553 seq_printf(m, "xfer_bytes %u.%01u kb\n",
3554 s->xfer_sect / 2, ASC_TENTHS(s->xfer_sect, 2));
3555
3556
3557 seq_printf(m, " avg_num_elem %u.%01u, ",
3558 s->xfer_elem / s->xfer_cnt,
3559 ASC_TENTHS(s->xfer_elem, s->xfer_cnt));
3560
3561 seq_printf(m, "avg_elem_size %u.%01u kb, ",
3562 (s->xfer_sect / 2) / s->xfer_elem,
3563 ASC_TENTHS((s->xfer_sect / 2), s->xfer_elem));
3564
3565 seq_printf(m, "avg_xfer_size %u.%01u kb\n",
3566 (s->xfer_sect / 2) / s->xfer_cnt,
3567 ASC_TENTHS((s->xfer_sect / 2), s->xfer_cnt));
3568 }
3569}
3570#endif
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581static int
3582advansys_show_info(struct seq_file *m, struct Scsi_Host *shost)
3583{
3584 struct asc_board *boardp = shost_priv(shost);
3585
3586 ASC_DBG(1, "begin\n");
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598 seq_printf(m, "%s\n", (char *)advansys_info(shost));
3599
3600
3601
3602 if (!ASC_NARROW_BOARD(boardp))
3603 asc_prt_adv_bios(m, shost);
3604
3605
3606
3607
3608 asc_prt_board_devices(m, shost);
3609
3610
3611
3612
3613 if (ASC_NARROW_BOARD(boardp))
3614 asc_prt_asc_board_eeprom(m, shost);
3615 else
3616 asc_prt_adv_board_eeprom(m, shost);
3617
3618
3619
3620
3621 asc_prt_driver_conf(m, shost);
3622
3623#ifdef ADVANSYS_STATS
3624
3625
3626
3627 asc_prt_board_stats(m, shost);
3628#endif
3629
3630
3631
3632
3633
3634 if (ASC_NARROW_BOARD(boardp))
3635 asc_prt_asc_board_info(m, shost);
3636 else
3637 asc_prt_adv_board_info(m, shost);
3638 return 0;
3639}
3640#endif
3641
3642static void asc_scsi_done(struct scsi_cmnd *scp)
3643{
3644 scsi_dma_unmap(scp);
3645 ASC_STATS(scp->device->host, done);
3646 scp->scsi_done(scp);
3647}
3648
3649static void AscSetBank(PortAddr iop_base, uchar bank)
3650{
3651 uchar val;
3652
3653 val = AscGetChipControl(iop_base) &
3654 (~
3655 (CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET |
3656 CC_CHIP_RESET));
3657 if (bank == 1) {
3658 val |= CC_BANK_ONE;
3659 } else if (bank == 2) {
3660 val |= CC_DIAG | CC_BANK_ONE;
3661 } else {
3662 val &= ~CC_BANK_ONE;
3663 }
3664 AscSetChipControl(iop_base, val);
3665}
3666
3667static void AscSetChipIH(PortAddr iop_base, ushort ins_code)
3668{
3669 AscSetBank(iop_base, 1);
3670 AscWriteChipIH(iop_base, ins_code);
3671 AscSetBank(iop_base, 0);
3672}
3673
3674static int AscStartChip(PortAddr iop_base)
3675{
3676 AscSetChipControl(iop_base, 0);
3677 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
3678 return (0);
3679 }
3680 return (1);
3681}
3682
3683static bool AscStopChip(PortAddr iop_base)
3684{
3685 uchar cc_val;
3686
3687 cc_val =
3688 AscGetChipControl(iop_base) &
3689 (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
3690 AscSetChipControl(iop_base, (uchar)(cc_val | CC_HALT));
3691 AscSetChipIH(iop_base, INS_HALT);
3692 AscSetChipIH(iop_base, INS_RFLAG_WTM);
3693 if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
3694 return false;
3695 }
3696 return true;
3697}
3698
3699static bool AscIsChipHalted(PortAddr iop_base)
3700{
3701 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
3702 if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
3703 return true;
3704 }
3705 }
3706 return false;
3707}
3708
3709static bool AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc)
3710{
3711 PortAddr iop_base;
3712 int i = 10;
3713
3714 iop_base = asc_dvc->iop_base;
3715 while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE)
3716 && (i-- > 0)) {
3717 mdelay(100);
3718 }
3719 AscStopChip(iop_base);
3720 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
3721 udelay(60);
3722 AscSetChipIH(iop_base, INS_RFLAG_WTM);
3723 AscSetChipIH(iop_base, INS_HALT);
3724 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
3725 AscSetChipControl(iop_base, CC_HALT);
3726 mdelay(200);
3727 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
3728 AscSetChipStatus(iop_base, 0);
3729 return (AscIsChipHalted(iop_base));
3730}
3731
3732static int AscFindSignature(PortAddr iop_base)
3733{
3734 ushort sig_word;
3735
3736 ASC_DBG(1, "AscGetChipSignatureByte(0x%x) 0x%x\n",
3737 iop_base, AscGetChipSignatureByte(iop_base));
3738 if (AscGetChipSignatureByte(iop_base) == (uchar)ASC_1000_ID1B) {
3739 ASC_DBG(1, "AscGetChipSignatureWord(0x%x) 0x%x\n",
3740 iop_base, AscGetChipSignatureWord(iop_base));
3741 sig_word = AscGetChipSignatureWord(iop_base);
3742 if ((sig_word == (ushort)ASC_1000_ID0W) ||
3743 (sig_word == (ushort)ASC_1000_ID0W_FIX)) {
3744 return (1);
3745 }
3746 }
3747 return (0);
3748}
3749
3750static void AscEnableInterrupt(PortAddr iop_base)
3751{
3752 ushort cfg;
3753
3754 cfg = AscGetChipCfgLsw(iop_base);
3755 AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
3756}
3757
3758static void AscDisableInterrupt(PortAddr iop_base)
3759{
3760 ushort cfg;
3761
3762 cfg = AscGetChipCfgLsw(iop_base);
3763 AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
3764}
3765
3766static uchar AscReadLramByte(PortAddr iop_base, ushort addr)
3767{
3768 unsigned char byte_data;
3769 unsigned short word_data;
3770
3771 if (isodd_word(addr)) {
3772 AscSetChipLramAddr(iop_base, addr - 1);
3773 word_data = AscGetChipLramData(iop_base);
3774 byte_data = (word_data >> 8) & 0xFF;
3775 } else {
3776 AscSetChipLramAddr(iop_base, addr);
3777 word_data = AscGetChipLramData(iop_base);
3778 byte_data = word_data & 0xFF;
3779 }
3780 return byte_data;
3781}
3782
3783static ushort AscReadLramWord(PortAddr iop_base, ushort addr)
3784{
3785 ushort word_data;
3786
3787 AscSetChipLramAddr(iop_base, addr);
3788 word_data = AscGetChipLramData(iop_base);
3789 return (word_data);
3790}
3791
3792static void
3793AscMemWordSetLram(PortAddr iop_base, ushort s_addr, ushort set_wval, int words)
3794{
3795 int i;
3796
3797 AscSetChipLramAddr(iop_base, s_addr);
3798 for (i = 0; i < words; i++) {
3799 AscSetChipLramData(iop_base, set_wval);
3800 }
3801}
3802
3803static void AscWriteLramWord(PortAddr iop_base, ushort addr, ushort word_val)
3804{
3805 AscSetChipLramAddr(iop_base, addr);
3806 AscSetChipLramData(iop_base, word_val);
3807}
3808
3809static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val)
3810{
3811 ushort word_data;
3812
3813 if (isodd_word(addr)) {
3814 addr--;
3815 word_data = AscReadLramWord(iop_base, addr);
3816 word_data &= 0x00FF;
3817 word_data |= (((ushort)byte_val << 8) & 0xFF00);
3818 } else {
3819 word_data = AscReadLramWord(iop_base, addr);
3820 word_data &= 0xFF00;
3821 word_data |= ((ushort)byte_val & 0x00FF);
3822 }
3823 AscWriteLramWord(iop_base, addr, word_data);
3824}
3825
3826
3827
3828
3829
3830
3831
3832static void
3833AscMemWordCopyPtrToLram(PortAddr iop_base, ushort s_addr,
3834 const uchar *s_buffer, int words)
3835{
3836 int i;
3837
3838 AscSetChipLramAddr(iop_base, s_addr);
3839 for (i = 0; i < 2 * words; i += 2) {
3840
3841
3842
3843
3844
3845
3846
3847
3848 outpw(iop_base + IOP_RAM_DATA,
3849 ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);
3850 }
3851}
3852
3853
3854
3855
3856
3857
3858
3859static void
3860AscMemDWordCopyPtrToLram(PortAddr iop_base,
3861 ushort s_addr, uchar *s_buffer, int dwords)
3862{
3863 int i;
3864
3865 AscSetChipLramAddr(iop_base, s_addr);
3866 for (i = 0; i < 4 * dwords; i += 4) {
3867 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);
3868 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 3] << 8) | s_buffer[i + 2]);
3869 }
3870}
3871
3872
3873
3874
3875
3876
3877
3878static void
3879AscMemWordCopyPtrFromLram(PortAddr iop_base,
3880 ushort s_addr, uchar *d_buffer, int words)
3881{
3882 int i;
3883 ushort word;
3884
3885 AscSetChipLramAddr(iop_base, s_addr);
3886 for (i = 0; i < 2 * words; i += 2) {
3887 word = inpw(iop_base + IOP_RAM_DATA);
3888 d_buffer[i] = word & 0xff;
3889 d_buffer[i + 1] = (word >> 8) & 0xff;
3890 }
3891}
3892
3893static u32 AscMemSumLramWord(PortAddr iop_base, ushort s_addr, int words)
3894{
3895 u32 sum = 0;
3896 int i;
3897
3898 for (i = 0; i < words; i++, s_addr += 2) {
3899 sum += AscReadLramWord(iop_base, s_addr);
3900 }
3901 return (sum);
3902}
3903
3904static void AscInitLram(ASC_DVC_VAR *asc_dvc)
3905{
3906 uchar i;
3907 ushort s_addr;
3908 PortAddr iop_base;
3909
3910 iop_base = asc_dvc->iop_base;
3911 AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
3912 (ushort)(((int)(asc_dvc->max_total_qng + 2 + 1) *
3913 64) >> 1));
3914 i = ASC_MIN_ACTIVE_QNO;
3915 s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
3916 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
3917 (uchar)(i + 1));
3918 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
3919 (uchar)(asc_dvc->max_total_qng));
3920 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
3921 (uchar)i);
3922 i++;
3923 s_addr += ASC_QBLK_SIZE;
3924 for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
3925 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
3926 (uchar)(i + 1));
3927 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
3928 (uchar)(i - 1));
3929 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
3930 (uchar)i);
3931 }
3932 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
3933 (uchar)ASC_QLINK_END);
3934 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
3935 (uchar)(asc_dvc->max_total_qng - 1));
3936 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
3937 (uchar)asc_dvc->max_total_qng);
3938 i++;
3939 s_addr += ASC_QBLK_SIZE;
3940 for (; i <= (uchar)(asc_dvc->max_total_qng + 3);
3941 i++, s_addr += ASC_QBLK_SIZE) {
3942 AscWriteLramByte(iop_base,
3943 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_FWD), i);
3944 AscWriteLramByte(iop_base,
3945 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_BWD), i);
3946 AscWriteLramByte(iop_base,
3947 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_QNO), i);
3948 }
3949}
3950
3951static u32
3952AscLoadMicroCode(PortAddr iop_base, ushort s_addr,
3953 const uchar *mcode_buf, ushort mcode_size)
3954{
3955 u32 chksum;
3956 ushort mcode_word_size;
3957 ushort mcode_chksum;
3958
3959
3960 mcode_word_size = (ushort)(mcode_size >> 1);
3961 AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
3962 AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
3963
3964 chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
3965 ASC_DBG(1, "chksum 0x%lx\n", (ulong)chksum);
3966 mcode_chksum = (ushort)AscMemSumLramWord(iop_base,
3967 (ushort)ASC_CODE_SEC_BEG,
3968 (ushort)((mcode_size -
3969 s_addr - (ushort)
3970 ASC_CODE_SEC_BEG) /
3971 2));
3972 ASC_DBG(1, "mcode_chksum 0x%lx\n", (ulong)mcode_chksum);
3973 AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
3974 AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
3975 return chksum;
3976}
3977
3978static void AscInitQLinkVar(ASC_DVC_VAR *asc_dvc)
3979{
3980 PortAddr iop_base;
3981 int i;
3982 ushort lram_addr;
3983
3984 iop_base = asc_dvc->iop_base;
3985 AscPutRiscVarFreeQHead(iop_base, 1);
3986 AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
3987 AscPutVarFreeQHead(iop_base, 1);
3988 AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
3989 AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
3990 (uchar)((int)asc_dvc->max_total_qng + 1));
3991 AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
3992 (uchar)((int)asc_dvc->max_total_qng + 2));
3993 AscWriteLramByte(iop_base, (ushort)ASCV_TOTAL_READY_Q_B,
3994 asc_dvc->max_total_qng);
3995 AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
3996 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
3997 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
3998 AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
3999 AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
4000 AscPutQDoneInProgress(iop_base, 0);
4001 lram_addr = ASC_QADR_BEG;
4002 for (i = 0; i < 32; i++, lram_addr += 2) {
4003 AscWriteLramWord(iop_base, lram_addr, 0);
4004 }
4005}
4006
4007static int AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
4008{
4009 int i;
4010 int warn_code;
4011 PortAddr iop_base;
4012 __le32 phy_addr;
4013 __le32 phy_size;
4014 struct asc_board *board = asc_dvc_to_board(asc_dvc);
4015
4016 iop_base = asc_dvc->iop_base;
4017 warn_code = 0;
4018 for (i = 0; i <= ASC_MAX_TID; i++) {
4019 AscPutMCodeInitSDTRAtID(iop_base, i,
4020 asc_dvc->cfg->sdtr_period_offset[i]);
4021 }
4022
4023 AscInitQLinkVar(asc_dvc);
4024 AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
4025 asc_dvc->cfg->disc_enable);
4026 AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
4027 ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
4028
4029
4030 BUG_ON((unsigned long)asc_dvc->overrun_buf & 7);
4031 asc_dvc->overrun_dma = dma_map_single(board->dev, asc_dvc->overrun_buf,
4032 ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE);
4033 if (dma_mapping_error(board->dev, asc_dvc->overrun_dma)) {
4034 warn_code = -ENOMEM;
4035 goto err_dma_map;
4036 }
4037 phy_addr = cpu_to_le32(asc_dvc->overrun_dma);
4038 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
4039 (uchar *)&phy_addr, 1);
4040 phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE);
4041 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
4042 (uchar *)&phy_size, 1);
4043
4044 asc_dvc->cfg->mcode_date =
4045 AscReadLramWord(iop_base, (ushort)ASCV_MC_DATE_W);
4046 asc_dvc->cfg->mcode_version =
4047 AscReadLramWord(iop_base, (ushort)ASCV_MC_VER_W);
4048
4049 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
4050 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
4051 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
4052 warn_code = -EINVAL;
4053 goto err_mcode_start;
4054 }
4055 if (AscStartChip(iop_base) != 1) {
4056 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
4057 warn_code = -EIO;
4058 goto err_mcode_start;
4059 }
4060
4061 return warn_code;
4062
4063err_mcode_start:
4064 dma_unmap_single(board->dev, asc_dvc->overrun_dma,
4065 ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE);
4066err_dma_map:
4067 asc_dvc->overrun_dma = 0;
4068 return warn_code;
4069}
4070
4071static int AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
4072{
4073 const struct firmware *fw;
4074 const char fwname[] = "advansys/mcode.bin";
4075 int err;
4076 unsigned long chksum;
4077 int warn_code;
4078 PortAddr iop_base;
4079
4080 iop_base = asc_dvc->iop_base;
4081 warn_code = 0;
4082 if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
4083 !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
4084 AscResetChipAndScsiBus(asc_dvc);
4085 mdelay(asc_dvc->scsi_reset_wait * 1000);
4086 }
4087 asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
4088 if (asc_dvc->err_code != 0)
4089 return ASC_ERROR;
4090 if (!AscFindSignature(asc_dvc->iop_base)) {
4091 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
4092 return warn_code;
4093 }
4094 AscDisableInterrupt(iop_base);
4095 AscInitLram(asc_dvc);
4096
4097 err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev);
4098 if (err) {
4099 printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
4100 fwname, err);
4101 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
4102 return err;
4103 }
4104 if (fw->size < 4) {
4105 printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
4106 fw->size, fwname);
4107 release_firmware(fw);
4108 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
4109 return -EINVAL;
4110 }
4111 chksum = (fw->data[3] << 24) | (fw->data[2] << 16) |
4112 (fw->data[1] << 8) | fw->data[0];
4113 ASC_DBG(1, "_asc_mcode_chksum 0x%lx\n", (ulong)chksum);
4114 if (AscLoadMicroCode(iop_base, 0, &fw->data[4],
4115 fw->size - 4) != chksum) {
4116 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
4117 release_firmware(fw);
4118 return warn_code;
4119 }
4120 release_firmware(fw);
4121 warn_code |= AscInitMicroCodeVar(asc_dvc);
4122 if (!asc_dvc->overrun_dma)
4123 return warn_code;
4124 asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
4125 AscEnableInterrupt(iop_base);
4126 return warn_code;
4127}
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151static int AdvLoadMicrocode(AdvPortAddr iop_base, const unsigned char *buf,
4152 int size, int memsize, int chksum)
4153{
4154 int i, j, end, len = 0;
4155 u32 sum;
4156
4157 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
4158
4159 for (i = 253 * 2; i < size; i++) {
4160 if (buf[i] == 0xff) {
4161 unsigned short word = (buf[i + 3] << 8) | buf[i + 2];
4162 for (j = 0; j < buf[i + 1]; j++) {
4163 AdvWriteWordAutoIncLram(iop_base, word);
4164 len += 2;
4165 }
4166 i += 3;
4167 } else if (buf[i] == 0xfe) {
4168 unsigned short word = (buf[i + 2] << 8) | buf[i + 1];
4169 AdvWriteWordAutoIncLram(iop_base, word);
4170 i += 2;
4171 len += 2;
4172 } else {
4173 unsigned int off = buf[i] * 2;
4174 unsigned short word = (buf[off + 1] << 8) | buf[off];
4175 AdvWriteWordAutoIncLram(iop_base, word);
4176 len += 2;
4177 }
4178 }
4179
4180 end = len;
4181
4182 while (len < memsize) {
4183 AdvWriteWordAutoIncLram(iop_base, 0);
4184 len += 2;
4185 }
4186
4187
4188 sum = 0;
4189 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
4190
4191 for (len = 0; len < end; len += 2) {
4192 sum += AdvReadWordAutoIncLram(iop_base);
4193 }
4194
4195 if (sum != chksum)
4196 return ASC_IERR_MCODE_CHKSUM;
4197
4198 return 0;
4199}
4200
4201static void AdvBuildCarrierFreelist(struct adv_dvc_var *adv_dvc)
4202{
4203 off_t carr_offset = 0, next_offset;
4204 dma_addr_t carr_paddr;
4205 int carr_num = ADV_CARRIER_BUFSIZE / sizeof(ADV_CARR_T), i;
4206
4207 for (i = 0; i < carr_num; i++) {
4208 carr_offset = i * sizeof(ADV_CARR_T);
4209
4210 carr_paddr = adv_dvc->carrier_addr + carr_offset;
4211
4212 adv_dvc->carrier[i].carr_pa = cpu_to_le32(carr_paddr);
4213 adv_dvc->carrier[i].carr_va = cpu_to_le32(carr_offset);
4214 adv_dvc->carrier[i].areq_vpa = 0;
4215 next_offset = carr_offset + sizeof(ADV_CARR_T);
4216 if (i == carr_num)
4217 next_offset = ~0;
4218 adv_dvc->carrier[i].next_vpa = cpu_to_le32(next_offset);
4219 }
4220
4221
4222
4223
4224
4225
4226 adv_dvc->carr_freelist = &adv_dvc->carrier[1];
4227}
4228
4229static ADV_CARR_T *adv_get_carrier(struct adv_dvc_var *adv_dvc, u32 offset)
4230{
4231 int index;
4232
4233 BUG_ON(offset > ADV_CARRIER_BUFSIZE);
4234
4235 index = offset / sizeof(ADV_CARR_T);
4236 return &adv_dvc->carrier[index];
4237}
4238
4239static ADV_CARR_T *adv_get_next_carrier(struct adv_dvc_var *adv_dvc)
4240{
4241 ADV_CARR_T *carrp = adv_dvc->carr_freelist;
4242 u32 next_vpa = le32_to_cpu(carrp->next_vpa);
4243
4244 if (next_vpa == 0 || next_vpa == ~0) {
4245 ASC_DBG(1, "invalid vpa offset 0x%x\n", next_vpa);
4246 return NULL;
4247 }
4248
4249 adv_dvc->carr_freelist = adv_get_carrier(adv_dvc, next_vpa);
4250
4251
4252
4253 carrp->next_vpa = cpu_to_le32(ADV_CQ_STOPPER);
4254
4255 return carrp;
4256}
4257
4258
4259
4260
4261static adv_req_t * adv_get_reqp(struct adv_dvc_var *adv_dvc, u32 offset)
4262{
4263 struct asc_board *boardp = adv_dvc->drv_ptr;
4264
4265 BUG_ON(offset > adv_dvc->max_host_qng);
4266 return &boardp->adv_reqp[offset];
4267}
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283static int
4284AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
4285 ushort idle_cmd, u32 idle_cmd_parameter)
4286{
4287 int result, i, j;
4288 AdvPortAddr iop_base;
4289
4290 iop_base = asc_dvc->iop_base;
4291
4292
4293
4294
4295
4296
4297 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort)0);
4298
4299
4300
4301
4302
4303
4304
4305 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
4306 cpu_to_le32(idle_cmd_parameter));
4307 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
4308
4309
4310
4311
4312 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
4313 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
4314
4315
4316
4317
4318
4319 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
4320 }
4321
4322
4323 for (i = 0; i < SCSI_WAIT_100_MSEC; i++) {
4324
4325 for (j = 0; j < SCSI_US_PER_MSEC; j++) {
4326 AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS,
4327 result);
4328 if (result != 0)
4329 return result;
4330 udelay(1);
4331 }
4332 }
4333
4334 BUG();
4335 return ADV_ERROR;
4336}
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347static int AdvResetSB(ADV_DVC_VAR *asc_dvc)
4348{
4349 int status;
4350
4351
4352
4353
4354
4355 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_START, 0L);
4356 if (status != ADV_TRUE) {
4357 return status;
4358 }
4359
4360
4361
4362
4363
4364
4365
4366 udelay(ASC_SCSI_RESET_HOLD_TIME_US);
4367
4368
4369
4370
4371
4372 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_END, 0L);
4373 if (status != ADV_TRUE) {
4374 return status;
4375 }
4376
4377 mdelay(asc_dvc->scsi_reset_wait * 1000);
4378
4379 return status;
4380}
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
4393{
4394 const struct firmware *fw;
4395 const char fwname[] = "advansys/3550.bin";
4396 AdvPortAddr iop_base;
4397 ushort warn_code;
4398 int begin_addr;
4399 int end_addr;
4400 ushort code_sum;
4401 int word;
4402 int i;
4403 int err;
4404 unsigned long chksum;
4405 ushort scsi_cfg1;
4406 uchar tid;
4407 ushort bios_mem[ASC_MC_BIOSLEN / 2];
4408 ushort wdtr_able = 0, sdtr_able, tagqng_able;
4409 uchar max_cmd[ADV_MAX_TID + 1];
4410
4411
4412 if (asc_dvc->err_code != 0)
4413 return ADV_ERROR;
4414
4415
4416
4417
4418 if (asc_dvc->chip_type != ADV_CHIP_ASC3550) {
4419 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
4420 return ADV_ERROR;
4421 }
4422
4423 warn_code = 0;
4424 iop_base = asc_dvc->iop_base;
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
4435 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
4436 bios_mem[i]);
4437 }
4438
4439
4440
4441
4442 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == 0x55AA) {
4443 ushort bios_version, major, minor;
4444
4445 bios_version =
4446 bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM) / 2];
4447 major = (bios_version >> 12) & 0xF;
4448 minor = (bios_version >> 8) & 0xF;
4449 if (major < 3 || (major == 3 && minor == 1)) {
4450
4451 AdvReadWordLram(iop_base, 0x120, wdtr_able);
4452 } else {
4453 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
4454 }
4455 }
4456 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
4457 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
4458 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
4459 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
4460 max_cmd[tid]);
4461 }
4462
4463 err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev);
4464 if (err) {
4465 printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
4466 fwname, err);
4467 asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM;
4468 return err;
4469 }
4470 if (fw->size < 4) {
4471 printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
4472 fw->size, fwname);
4473 release_firmware(fw);
4474 asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM;
4475 return -EINVAL;
4476 }
4477 chksum = (fw->data[3] << 24) | (fw->data[2] << 16) |
4478 (fw->data[1] << 8) | fw->data[0];
4479 asc_dvc->err_code = AdvLoadMicrocode(iop_base, &fw->data[4],
4480 fw->size - 4, ADV_3550_MEMSIZE,
4481 chksum);
4482 release_firmware(fw);
4483 if (asc_dvc->err_code)
4484 return ADV_ERROR;
4485
4486
4487
4488
4489 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
4490 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
4491 bios_mem[i]);
4492 }
4493
4494
4495
4496
4497
4498 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
4499 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
4500 code_sum = 0;
4501 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
4502 for (word = begin_addr; word < end_addr; word += 2) {
4503 code_sum += AdvReadWordAutoIncLram(iop_base);
4504 }
4505 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
4506
4507
4508
4509
4510 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
4511 asc_dvc->cfg->mcode_date);
4512 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
4513 asc_dvc->cfg->mcode_version);
4514
4515
4516
4517
4518 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
4519
4520
4521
4522
4523
4524
4525
4526 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
4527 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
4528 word |= CONTROL_FLAG_IGNORE_PERR;
4529 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
4530 }
4531
4532
4533
4534
4535
4536 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
4537 START_CTL_EMFU | READ_CMD_MRM);
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
4552 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
4553 asc_dvc->wdtr_able);
4554 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
4555 asc_dvc->sdtr_able);
4556 }
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580 word = 0;
4581 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
4582 if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able) {
4583
4584 word |= (0x3 << (4 * (tid % 4)));
4585 } else {
4586
4587 word |= (0x2 << (4 * (tid % 4)));
4588 }
4589 if (tid == 3) {
4590 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
4591 word = 0;
4592 } else if (tid == 7) {
4593 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
4594 word = 0;
4595 } else if (tid == 11) {
4596 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
4597 word = 0;
4598 } else if (tid == 15) {
4599 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
4600
4601 }
4602 }
4603
4604
4605
4606
4607 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
4608 asc_dvc->cfg->disc_enable);
4609
4610
4611
4612
4613
4614
4615
4616 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
4617 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
4618 asc_dvc->chip_scsi_id);
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
4629
4630
4631
4632
4633 if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
4634 (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) {
4635 asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
4636 return ADV_ERROR;
4637 }
4638
4639
4640
4641
4642
4643
4644 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
4645 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
4646 return ADV_ERROR;
4647 }
4648
4649
4650
4651
4652
4653 if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0) {
4654 asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
4655 return ADV_ERROR;
4656 }
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666 if (asc_dvc->cfg->termination == 0) {
4667
4668
4669
4670
4671 asc_dvc->cfg->termination |= TERM_CTL_SEL;
4672
4673 switch (scsi_cfg1 & CABLE_DETECT) {
4674
4675 case 0x3:
4676 case 0x7:
4677 case 0xB:
4678 case 0xD:
4679 case 0xE:
4680 case 0xF:
4681 asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
4682 break;
4683
4684
4685 case 0x1:
4686 case 0x5:
4687 case 0x9:
4688 case 0xA:
4689 case 0xC:
4690 asc_dvc->cfg->termination |= TERM_CTL_H;
4691 break;
4692
4693
4694 case 0x2:
4695 case 0x6:
4696 break;
4697 }
4698 }
4699
4700
4701
4702
4703 scsi_cfg1 &= ~TERM_CTL;
4704
4705
4706
4707
4708
4709
4710
4711 scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
4723 FLTR_DISABLE | scsi_cfg1);
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
4737 BIOS_EN | RAM_SZ_8KB);
4738
4739
4740
4741
4742
4743
4744
4745 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
4746 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
4747
4748 AdvBuildCarrierFreelist(asc_dvc);
4749
4750
4751
4752
4753
4754 asc_dvc->icq_sp = adv_get_next_carrier(asc_dvc);
4755 if (!asc_dvc->icq_sp) {
4756 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
4757 return ADV_ERROR;
4758 }
4759
4760
4761
4762
4763 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
4764
4765
4766
4767
4768 asc_dvc->irq_sp = adv_get_next_carrier(asc_dvc);
4769 if (!asc_dvc->irq_sp) {
4770 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
4771 return ADV_ERROR;
4772 }
4773
4774
4775
4776
4777 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
4778 asc_dvc->carr_pending_cnt = 0;
4779
4780 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
4781 (ADV_INTR_ENABLE_HOST_INTR |
4782 ADV_INTR_ENABLE_GLOBAL_INTR));
4783
4784 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
4785 AdvWriteWordRegister(iop_base, IOPW_PC, word);
4786
4787
4788 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
4789
4790
4791
4792
4793
4794
4795 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
4796
4797
4798
4799
4800
4801 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
4802 0x55AA) {
4803
4804
4805
4806 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
4807 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
4808 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
4809 tagqng_able);
4810 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
4811 AdvWriteByteLram(iop_base,
4812 ASC_MC_NUMBER_OF_MAX_CMD + tid,
4813 max_cmd[tid]);
4814 }
4815 } else {
4816 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
4817 warn_code = ASC_WARN_BUSRESET_ERROR;
4818 }
4819 }
4820 }
4821
4822 return warn_code;
4823}
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
4836{
4837 const struct firmware *fw;
4838 const char fwname[] = "advansys/38C0800.bin";
4839 AdvPortAddr iop_base;
4840 ushort warn_code;
4841 int begin_addr;
4842 int end_addr;
4843 ushort code_sum;
4844 int word;
4845 int i;
4846 int err;
4847 unsigned long chksum;
4848 ushort scsi_cfg1;
4849 uchar byte;
4850 uchar tid;
4851 ushort bios_mem[ASC_MC_BIOSLEN / 2];
4852 ushort wdtr_able, sdtr_able, tagqng_able;
4853 uchar max_cmd[ADV_MAX_TID + 1];
4854
4855
4856 if (asc_dvc->err_code != 0)
4857 return ADV_ERROR;
4858
4859
4860
4861
4862 if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800) {
4863 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
4864 return ADV_ERROR;
4865 }
4866
4867 warn_code = 0;
4868 iop_base = asc_dvc->iop_base;
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
4879 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
4880 bios_mem[i]);
4881 }
4882
4883
4884
4885
4886 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
4887 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
4888 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
4889 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
4890 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
4891 max_cmd[tid]);
4892 }
4893
4894
4895
4896
4897
4898
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 for (i = 0; i < 2; i++) {
4924 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
4925 mdelay(10);
4926 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
4927 if ((byte & RAM_TEST_DONE) == 0
4928 || (byte & 0x0F) != PRE_TEST_VALUE) {
4929 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
4930 return ADV_ERROR;
4931 }
4932
4933 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
4934 mdelay(10);
4935 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
4936 != NORMAL_VALUE) {
4937 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
4938 return ADV_ERROR;
4939 }
4940 }
4941
4942
4943
4944
4945
4946
4947
4948
4949 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
4950 mdelay(10);
4951
4952 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
4953 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
4954
4955 asc_dvc->bist_err_code = byte;
4956 asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST;
4957 return ADV_ERROR;
4958 }
4959
4960
4961 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
4962
4963 err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev);
4964 if (err) {
4965 printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
4966 fwname, err);
4967 asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM;
4968 return err;
4969 }
4970 if (fw->size < 4) {
4971 printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
4972 fw->size, fwname);
4973 release_firmware(fw);
4974 asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM;
4975 return -EINVAL;
4976 }
4977 chksum = (fw->data[3] << 24) | (fw->data[2] << 16) |
4978 (fw->data[1] << 8) | fw->data[0];
4979 asc_dvc->err_code = AdvLoadMicrocode(iop_base, &fw->data[4],
4980 fw->size - 4, ADV_38C0800_MEMSIZE,
4981 chksum);
4982 release_firmware(fw);
4983 if (asc_dvc->err_code)
4984 return ADV_ERROR;
4985
4986
4987
4988
4989 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
4990 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
4991 bios_mem[i]);
4992 }
4993
4994
4995
4996
4997
4998 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
4999 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
5000 code_sum = 0;
5001 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
5002 for (word = begin_addr; word < end_addr; word += 2) {
5003 code_sum += AdvReadWordAutoIncLram(iop_base);
5004 }
5005 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
5006
5007
5008
5009
5010 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
5011 asc_dvc->cfg->mcode_date);
5012 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
5013 asc_dvc->cfg->mcode_version);
5014
5015
5016
5017
5018 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
5029 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
5030 scsi_cfg1 | DIS_TERM_DRV);
5031
5032
5033
5034
5035
5036
5037
5038 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
5039 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
5040 word |= CONTROL_FLAG_IGNORE_PERR;
5041 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
5042 }
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
5053 BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH |
5054 READ_CMD_MRM);
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
5069 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
5070 asc_dvc->wdtr_able);
5071 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
5072 asc_dvc->sdtr_able);
5073 }
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
5085 asc_dvc->cfg->disc_enable);
5086 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
5087 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
5088 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
5089 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
5090
5091
5092
5093
5094
5095
5096
5097 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
5098 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
5099 asc_dvc->chip_scsi_id);
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
5110
5111
5112
5113
5114
5115
5116 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
5117 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
5118 return ADV_ERROR;
5119 }
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132 if (scsi_cfg1 & HVD) {
5133 asc_dvc->err_code = ASC_IERR_HVD_DEVICE;
5134 return ADV_ERROR;
5135 }
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
5146
5147 switch (scsi_cfg1 & C_DET_SE) {
5148
5149 case 0x1:
5150 case 0x2:
5151 case 0x3:
5152 asc_dvc->cfg->termination |= TERM_SE;
5153 break;
5154
5155
5156 case 0x0:
5157 asc_dvc->cfg->termination |= TERM_SE_HI;
5158 break;
5159 }
5160 }
5161
5162 if ((asc_dvc->cfg->termination & TERM_LVD) == 0) {
5163
5164 switch (scsi_cfg1 & C_DET_LVD) {
5165
5166 case 0x4:
5167 case 0x8:
5168 case 0xC:
5169 asc_dvc->cfg->termination |= TERM_LVD;
5170 break;
5171
5172
5173 case 0x0:
5174 break;
5175 }
5176 }
5177
5178
5179
5180
5181 scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
5182
5183
5184
5185
5186 scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
5187
5188
5189
5190
5191
5192
5193 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
5218 BIOS_EN | RAM_SZ_16KB);
5219
5220
5221
5222
5223
5224
5225
5226 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
5227 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
5228
5229 AdvBuildCarrierFreelist(asc_dvc);
5230
5231
5232
5233
5234
5235 asc_dvc->icq_sp = adv_get_next_carrier(asc_dvc);
5236 if (!asc_dvc->icq_sp) {
5237 ASC_DBG(0, "Failed to get ICQ carrier\n");
5238 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
5239 return ADV_ERROR;
5240 }
5241
5242
5243
5244
5245
5246 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
5247
5248
5249
5250
5251 asc_dvc->irq_sp = adv_get_next_carrier(asc_dvc);
5252 if (!asc_dvc->irq_sp) {
5253 ASC_DBG(0, "Failed to get IRQ carrier\n");
5254 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
5255 return ADV_ERROR;
5256 }
5257
5258
5259
5260
5261
5262
5263 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
5264 asc_dvc->carr_pending_cnt = 0;
5265
5266 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
5267 (ADV_INTR_ENABLE_HOST_INTR |
5268 ADV_INTR_ENABLE_GLOBAL_INTR));
5269
5270 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
5271 AdvWriteWordRegister(iop_base, IOPW_PC, word);
5272
5273
5274 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
5275
5276
5277
5278
5279
5280
5281 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
5282
5283
5284
5285
5286
5287 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
5288 0x55AA) {
5289
5290
5291
5292 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
5293 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
5294 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
5295 tagqng_able);
5296 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
5297 AdvWriteByteLram(iop_base,
5298 ASC_MC_NUMBER_OF_MAX_CMD + tid,
5299 max_cmd[tid]);
5300 }
5301 } else {
5302 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
5303 warn_code = ASC_WARN_BUSRESET_ERROR;
5304 }
5305 }
5306 }
5307
5308 return warn_code;
5309}
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
5322{
5323 const struct firmware *fw;
5324 const char fwname[] = "advansys/38C1600.bin";
5325 AdvPortAddr iop_base;
5326 ushort warn_code;
5327 int begin_addr;
5328 int end_addr;
5329 ushort code_sum;
5330 long word;
5331 int i;
5332 int err;
5333 unsigned long chksum;
5334 ushort scsi_cfg1;
5335 uchar byte;
5336 uchar tid;
5337 ushort bios_mem[ASC_MC_BIOSLEN / 2];
5338 ushort wdtr_able, sdtr_able, ppr_able, tagqng_able;
5339 uchar max_cmd[ASC_MAX_TID + 1];
5340
5341
5342 if (asc_dvc->err_code != 0) {
5343 return ADV_ERROR;
5344 }
5345
5346
5347
5348
5349 if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
5350 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
5351 return ADV_ERROR;
5352 }
5353
5354 warn_code = 0;
5355 iop_base = asc_dvc->iop_base;
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
5366 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
5367 bios_mem[i]);
5368 }
5369
5370
5371
5372
5373 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
5374 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
5375 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
5376 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
5377 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
5378 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
5379 max_cmd[tid]);
5380 }
5381
5382
5383
5384
5385
5386
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 for (i = 0; i < 2; i++) {
5412 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
5413 mdelay(10);
5414 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
5415 if ((byte & RAM_TEST_DONE) == 0
5416 || (byte & 0x0F) != PRE_TEST_VALUE) {
5417 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
5418 return ADV_ERROR;
5419 }
5420
5421 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
5422 mdelay(10);
5423 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
5424 != NORMAL_VALUE) {
5425 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
5426 return ADV_ERROR;
5427 }
5428 }
5429
5430
5431
5432
5433
5434
5435
5436
5437 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
5438 mdelay(10);
5439
5440 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
5441 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
5442
5443 asc_dvc->bist_err_code = byte;
5444 asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST;
5445 return ADV_ERROR;
5446 }
5447
5448
5449 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
5450
5451 err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev);
5452 if (err) {
5453 printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
5454 fwname, err);
5455 asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM;
5456 return err;
5457 }
5458 if (fw->size < 4) {
5459 printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
5460 fw->size, fwname);
5461 release_firmware(fw);
5462 asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM;
5463 return -EINVAL;
5464 }
5465 chksum = (fw->data[3] << 24) | (fw->data[2] << 16) |
5466 (fw->data[1] << 8) | fw->data[0];
5467 asc_dvc->err_code = AdvLoadMicrocode(iop_base, &fw->data[4],
5468 fw->size - 4, ADV_38C1600_MEMSIZE,
5469 chksum);
5470 release_firmware(fw);
5471 if (asc_dvc->err_code)
5472 return ADV_ERROR;
5473
5474
5475
5476
5477 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
5478 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
5479 bios_mem[i]);
5480 }
5481
5482
5483
5484
5485
5486 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
5487 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
5488 code_sum = 0;
5489 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
5490 for (word = begin_addr; word < end_addr; word += 2) {
5491 code_sum += AdvReadWordAutoIncLram(iop_base);
5492 }
5493 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
5494
5495
5496
5497
5498 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
5499 asc_dvc->cfg->mcode_date);
5500 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
5501 asc_dvc->cfg->mcode_version);
5502
5503
5504
5505
5506 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
5517 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
5518 scsi_cfg1 | DIS_TERM_DRV);
5519
5520
5521
5522
5523
5524
5525
5526 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
5527 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
5528 word |= CONTROL_FLAG_IGNORE_PERR;
5529 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
5530 }
5531
5532
5533
5534
5535
5536
5537
5538 if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0) {
5539 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
5540 word |= CONTROL_FLAG_ENABLE_AIPP;
5541 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
5542 }
5543
5544
5545
5546
5547
5548 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
5549 FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
5564 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
5565 asc_dvc->wdtr_able);
5566 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
5567 asc_dvc->sdtr_able);
5568 }
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
5580 asc_dvc->cfg->disc_enable);
5581 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
5582 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
5583 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
5584 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
5585
5586
5587
5588
5589
5590
5591
5592 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
5593 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
5594 asc_dvc->chip_scsi_id);
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
5606
5607
5608
5609
5610
5611
5612 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
5613 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
5614 return ADV_ERROR;
5615 }
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625 if (scsi_cfg1 & HVD) {
5626 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
5627 return ADV_ERROR;
5628 }
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
5644 struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc);
5645
5646 switch (scsi_cfg1 & C_DET_SE) {
5647
5648 case 0x1:
5649 case 0x2:
5650 case 0x3:
5651 asc_dvc->cfg->termination |= TERM_SE;
5652 break;
5653
5654 case 0x0:
5655 if (PCI_FUNC(pdev->devfn) == 0) {
5656
5657 } else {
5658
5659 asc_dvc->cfg->termination |= TERM_SE_HI;
5660 }
5661 break;
5662 }
5663 }
5664
5665
5666
5667
5668 scsi_cfg1 &= ~TERM_SE;
5669
5670
5671
5672
5673 scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
5674
5675
5676
5677
5678
5679
5680
5681
5682 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
5715 BIOS_EN | RAM_SZ_16KB);
5716
5717
5718
5719
5720
5721
5722
5723 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
5724 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
5725
5726 AdvBuildCarrierFreelist(asc_dvc);
5727
5728
5729
5730
5731 asc_dvc->icq_sp = adv_get_next_carrier(asc_dvc);
5732 if (!asc_dvc->icq_sp) {
5733 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
5734 return ADV_ERROR;
5735 }
5736
5737
5738
5739
5740
5741
5742 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
5743 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
5744 le32_to_cpu(asc_dvc->icq_sp->carr_pa));
5745
5746
5747
5748
5749 asc_dvc->irq_sp = adv_get_next_carrier(asc_dvc);
5750 if (!asc_dvc->irq_sp) {
5751 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
5752 return ADV_ERROR;
5753 }
5754
5755
5756
5757
5758 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
5759 asc_dvc->carr_pending_cnt = 0;
5760
5761 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
5762 (ADV_INTR_ENABLE_HOST_INTR |
5763 ADV_INTR_ENABLE_GLOBAL_INTR));
5764 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
5765 AdvWriteWordRegister(iop_base, IOPW_PC, word);
5766
5767
5768 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
5769
5770
5771
5772
5773
5774
5775 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
5776
5777
5778
5779
5780 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
5781 0x55AA) {
5782
5783
5784
5785 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
5786 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
5787 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
5788 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
5789 tagqng_able);
5790 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
5791 AdvWriteByteLram(iop_base,
5792 ASC_MC_NUMBER_OF_MAX_CMD + tid,
5793 max_cmd[tid]);
5794 }
5795 } else {
5796 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
5797 warn_code = ASC_WARN_BUSRESET_ERROR;
5798 }
5799 }
5800 }
5801
5802 return warn_code;
5803}
5804
5805
5806
5807
5808
5809
5810
5811
5812static int AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
5813{
5814 int status;
5815 ushort wdtr_able, sdtr_able, tagqng_able;
5816 ushort ppr_able = 0;
5817 uchar tid, max_cmd[ADV_MAX_TID + 1];
5818 AdvPortAddr iop_base;
5819 ushort bios_sig;
5820
5821 iop_base = asc_dvc->iop_base;
5822
5823
5824
5825
5826 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
5827 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
5828 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
5829 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
5830 }
5831 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
5832 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
5833 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
5834 max_cmd[tid]);
5835 }
5836
5837
5838
5839
5840
5841
5842
5843 AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
5844 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
5845
5846
5847
5848
5849 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
5850 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
5851 mdelay(100);
5852 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
5853 ADV_CTRL_REG_CMD_WR_IO_REG);
5854
5855
5856
5857
5858
5859 asc_dvc->err_code = 0;
5860 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
5861 status = AdvInitAsc38C1600Driver(asc_dvc);
5862 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
5863 status = AdvInitAsc38C0800Driver(asc_dvc);
5864 } else {
5865 status = AdvInitAsc3550Driver(asc_dvc);
5866 }
5867
5868
5869 if (status == 0) {
5870 status = ADV_TRUE;
5871 } else {
5872 status = ADV_FALSE;
5873 }
5874
5875
5876
5877
5878 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
5879
5880
5881
5882
5883 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
5884 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
5885 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
5886 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
5887 }
5888 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
5889 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
5890 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
5891 max_cmd[tid]);
5892 }
5893
5894 return status;
5895}
5896
5897
5898
5899
5900static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
5901{
5902 switch (code) {
5903 case ADV_ASYNC_SCSI_BUS_RESET_DET:
5904
5905
5906
5907 ASC_DBG(0, "ADV_ASYNC_SCSI_BUS_RESET_DET\n");
5908 break;
5909
5910 case ADV_ASYNC_RDMA_FAILURE:
5911
5912
5913
5914
5915
5916 ASC_DBG(0, "ADV_ASYNC_RDMA_FAILURE\n");
5917 AdvResetChipAndSB(adv_dvc_varp);
5918 break;
5919
5920 case ADV_HOST_SCSI_BUS_RESET:
5921
5922
5923
5924 ASC_DBG(0, "ADV_HOST_SCSI_BUS_RESET\n");
5925 break;
5926
5927 default:
5928 ASC_DBG(0, "unknown code 0x%x\n", code);
5929 break;
5930 }
5931}
5932
5933
5934
5935
5936
5937
5938static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
5939{
5940 struct asc_board *boardp = adv_dvc_varp->drv_ptr;
5941 adv_req_t *reqp;
5942 adv_sgblk_t *sgblkp;
5943 struct scsi_cmnd *scp;
5944 u32 resid_cnt;
5945 dma_addr_t sense_addr;
5946
5947 ASC_DBG(1, "adv_dvc_varp 0x%p, scsiqp 0x%p\n",
5948 adv_dvc_varp, scsiqp);
5949 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
5950
5951
5952
5953
5954
5955
5956 scp = scsi_host_find_tag(boardp->shost, scsiqp->srb_tag);
5957
5958 ASC_DBG(1, "scp 0x%p\n", scp);
5959 if (scp == NULL) {
5960 ASC_PRINT
5961 ("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
5962 return;
5963 }
5964 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
5965
5966 reqp = (adv_req_t *)scp->host_scribble;
5967 ASC_DBG(1, "reqp 0x%lx\n", (ulong)reqp);
5968 if (reqp == NULL) {
5969 ASC_PRINT("adv_isr_callback: reqp is NULL\n");
5970 return;
5971 }
5972
5973
5974
5975
5976 scp->host_scribble = NULL;
5977 reqp->cmndp = NULL;
5978
5979 ASC_STATS(boardp->shost, callback);
5980 ASC_DBG(1, "shost 0x%p\n", boardp->shost);
5981
5982 sense_addr = le32_to_cpu(scsiqp->sense_addr);
5983 dma_unmap_single(boardp->dev, sense_addr,
5984 SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
5985
5986
5987
5988
5989 switch (scsiqp->done_status) {
5990 case QD_NO_ERROR:
5991 ASC_DBG(2, "QD_NO_ERROR\n");
5992 scp->result = 0;
5993
5994
5995
5996
5997
5998
5999
6000 resid_cnt = le32_to_cpu(scsiqp->data_cnt);
6001 if (scsi_bufflen(scp) != 0 && resid_cnt != 0 &&
6002 resid_cnt <= scsi_bufflen(scp)) {
6003 ASC_DBG(1, "underrun condition %lu bytes\n",
6004 (ulong)resid_cnt);
6005 scsi_set_resid(scp, resid_cnt);
6006 }
6007 break;
6008
6009 case QD_WITH_ERROR:
6010 ASC_DBG(2, "QD_WITH_ERROR\n");
6011 switch (scsiqp->host_status) {
6012 case QHSTA_NO_ERROR:
6013 if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
6014 ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n");
6015 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
6016 SCSI_SENSE_BUFFERSIZE);
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
6030 STATUS_BYTE(scsiqp->scsi_status);
6031 } else {
6032 scp->result = STATUS_BYTE(scsiqp->scsi_status);
6033 }
6034 break;
6035
6036 default:
6037
6038 ASC_DBG(1, "host_status 0x%x\n", scsiqp->host_status);
6039 scp->result = HOST_BYTE(DID_BAD_TARGET);
6040 break;
6041 }
6042 break;
6043
6044 case QD_ABORTED_BY_HOST:
6045 ASC_DBG(1, "QD_ABORTED_BY_HOST\n");
6046 scp->result =
6047 HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
6048 break;
6049
6050 default:
6051 ASC_DBG(1, "done_status 0x%x\n", scsiqp->done_status);
6052 scp->result =
6053 HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
6054 break;
6055 }
6056
6057
6058
6059
6060
6061
6062 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
6063 scsiqp->done_status == QD_NO_ERROR &&
6064 scsiqp->host_status == QHSTA_NO_ERROR) {
6065 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
6066 }
6067
6068 asc_scsi_done(scp);
6069
6070
6071
6072
6073 while ((sgblkp = reqp->sgblkp) != NULL) {
6074
6075 reqp->sgblkp = sgblkp->next_sgblkp;
6076
6077 dma_pool_free(boardp->adv_sgblk_pool, sgblkp,
6078 sgblkp->sg_addr);
6079 }
6080
6081 ASC_DBG(1, "done\n");
6082}
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103static int AdvISR(ADV_DVC_VAR *asc_dvc)
6104{
6105 AdvPortAddr iop_base;
6106 uchar int_stat;
6107 ADV_CARR_T *free_carrp;
6108 __le32 irq_next_vpa;
6109 ADV_SCSI_REQ_Q *scsiq;
6110 adv_req_t *reqp;
6111
6112 iop_base = asc_dvc->iop_base;
6113
6114
6115 int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
6116
6117 if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
6118 ADV_INTR_STATUS_INTRC)) == 0) {
6119 return ADV_FALSE;
6120 }
6121
6122
6123
6124
6125
6126
6127 if (int_stat & ADV_INTR_STATUS_INTRB) {
6128 uchar intrb_code;
6129
6130 AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
6131
6132 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
6133 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
6134 if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
6135 asc_dvc->carr_pending_cnt != 0) {
6136 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
6137 ADV_TICKLE_A);
6138 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
6139 AdvWriteByteRegister(iop_base,
6140 IOPB_TICKLE,
6141 ADV_TICKLE_NOP);
6142 }
6143 }
6144 }
6145
6146 adv_async_callback(asc_dvc, intrb_code);
6147 }
6148
6149
6150
6151
6152 while (((irq_next_vpa =
6153 le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ADV_RQ_DONE) != 0) {
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163 u32 pa_offset = le32_to_cpu(asc_dvc->irq_sp->areq_vpa);
6164 ASC_DBG(1, "irq_sp %p areq_vpa %u\n",
6165 asc_dvc->irq_sp, pa_offset);
6166 reqp = adv_get_reqp(asc_dvc, pa_offset);
6167 scsiq = &reqp->scsi_req_q;
6168
6169
6170
6171
6172
6173
6174 if ((irq_next_vpa & ADV_RQ_GOOD) != 0) {
6175 scsiq->done_status = QD_NO_ERROR;
6176 scsiq->host_status = scsiq->scsi_status = 0;
6177 scsiq->data_cnt = 0L;
6178 }
6179
6180
6181
6182
6183
6184
6185 free_carrp = asc_dvc->irq_sp;
6186 asc_dvc->irq_sp = adv_get_carrier(asc_dvc,
6187 ADV_GET_CARRP(irq_next_vpa));
6188
6189 free_carrp->next_vpa = asc_dvc->carr_freelist->carr_va;
6190 asc_dvc->carr_freelist = free_carrp;
6191 asc_dvc->carr_pending_cnt--;
6192
6193
6194
6195
6196 scsiq->cntl = 0;
6197
6198
6199
6200
6201
6202 adv_isr_callback(asc_dvc, scsiq);
6203
6204
6205
6206
6207
6208
6209
6210 }
6211 return ADV_TRUE;
6212}
6213
6214static int AscSetLibErrorCode(ASC_DVC_VAR *asc_dvc, ushort err_code)
6215{
6216 if (asc_dvc->err_code == 0) {
6217 asc_dvc->err_code = err_code;
6218 AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
6219 err_code);
6220 }
6221 return err_code;
6222}
6223
6224static void AscAckInterrupt(PortAddr iop_base)
6225{
6226 uchar host_flag;
6227 uchar risc_flag;
6228 ushort loop;
6229
6230 loop = 0;
6231 do {
6232 risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
6233 if (loop++ > 0x7FFF) {
6234 break;
6235 }
6236 } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
6237 host_flag =
6238 AscReadLramByte(iop_base,
6239 ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
6240 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
6241 (uchar)(host_flag | ASC_HOST_FLAG_ACK_INT));
6242 AscSetChipStatus(iop_base, CIW_INT_ACK);
6243 loop = 0;
6244 while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
6245 AscSetChipStatus(iop_base, CIW_INT_ACK);
6246 if (loop++ > 3) {
6247 break;
6248 }
6249 }
6250 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
6251}
6252
6253static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time)
6254{
6255 const uchar *period_table;
6256 int max_index;
6257 int min_index;
6258 int i;
6259
6260 period_table = asc_dvc->sdtr_period_tbl;
6261 max_index = (int)asc_dvc->max_sdtr_index;
6262 min_index = (int)asc_dvc->min_sdtr_index;
6263 if ((syn_time <= period_table[max_index])) {
6264 for (i = min_index; i < (max_index - 1); i++) {
6265 if (syn_time <= period_table[i]) {
6266 return (uchar)i;
6267 }
6268 }
6269 return (uchar)max_index;
6270 } else {
6271 return (uchar)(max_index + 1);
6272 }
6273}
6274
6275static uchar
6276AscMsgOutSDTR(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar sdtr_offset)
6277{
6278 PortAddr iop_base = asc_dvc->iop_base;
6279 uchar sdtr_period_index = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
6280 EXT_MSG sdtr_buf = {
6281 .msg_type = EXTENDED_MESSAGE,
6282 .msg_len = MS_SDTR_LEN,
6283 .msg_req = EXTENDED_SDTR,
6284 .xfer_period = sdtr_period,
6285 .req_ack_offset = sdtr_offset,
6286 };
6287 sdtr_offset &= ASC_SYN_MAX_OFFSET;
6288
6289 if (sdtr_period_index <= asc_dvc->max_sdtr_index) {
6290 AscMemWordCopyPtrToLram(iop_base, ASCV_MSGOUT_BEG,
6291 (uchar *)&sdtr_buf,
6292 sizeof(EXT_MSG) >> 1);
6293 return ((sdtr_period_index << 4) | sdtr_offset);
6294 } else {
6295 sdtr_buf.req_ack_offset = 0;
6296 AscMemWordCopyPtrToLram(iop_base, ASCV_MSGOUT_BEG,
6297 (uchar *)&sdtr_buf,
6298 sizeof(EXT_MSG) >> 1);
6299 return 0;
6300 }
6301}
6302
6303static uchar
6304AscCalSDTRData(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar syn_offset)
6305{
6306 uchar byte;
6307 uchar sdtr_period_ix;
6308
6309 sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
6310 if (sdtr_period_ix > asc_dvc->max_sdtr_index)
6311 return 0xFF;
6312 byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
6313 return byte;
6314}
6315
6316static bool AscSetChipSynRegAtID(PortAddr iop_base, uchar id, uchar sdtr_data)
6317{
6318 ASC_SCSI_BIT_ID_TYPE org_id;
6319 int i;
6320 bool sta = true;
6321
6322 AscSetBank(iop_base, 1);
6323 org_id = AscReadChipDvcID(iop_base);
6324 for (i = 0; i <= ASC_MAX_TID; i++) {
6325 if (org_id == (0x01 << i))
6326 break;
6327 }
6328 org_id = (ASC_SCSI_BIT_ID_TYPE) i;
6329 AscWriteChipDvcID(iop_base, id);
6330 if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
6331 AscSetBank(iop_base, 0);
6332 AscSetChipSyn(iop_base, sdtr_data);
6333 if (AscGetChipSyn(iop_base) != sdtr_data) {
6334 sta = false;
6335 }
6336 } else {
6337 sta = false;
6338 }
6339 AscSetBank(iop_base, 1);
6340 AscWriteChipDvcID(iop_base, org_id);
6341 AscSetBank(iop_base, 0);
6342 return (sta);
6343}
6344
6345static void AscSetChipSDTR(PortAddr iop_base, uchar sdtr_data, uchar tid_no)
6346{
6347 AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
6348 AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
6349}
6350
6351static void AscIsrChipHalted(ASC_DVC_VAR *asc_dvc)
6352{
6353 EXT_MSG ext_msg;
6354 EXT_MSG out_msg;
6355 ushort halt_q_addr;
6356 bool sdtr_accept;
6357 ushort int_halt_code;
6358 ASC_SCSI_BIT_ID_TYPE scsi_busy;
6359 ASC_SCSI_BIT_ID_TYPE target_id;
6360 PortAddr iop_base;
6361 uchar tag_code;
6362 uchar q_status;
6363 uchar halt_qp;
6364 uchar sdtr_data;
6365 uchar target_ix;
6366 uchar q_cntl, tid_no;
6367 uchar cur_dvc_qng;
6368 uchar asyn_sdtr;
6369 uchar scsi_status;
6370 struct asc_board *boardp;
6371
6372 BUG_ON(!asc_dvc->drv_ptr);
6373 boardp = asc_dvc->drv_ptr;
6374
6375 iop_base = asc_dvc->iop_base;
6376 int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
6377
6378 halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
6379 halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
6380 target_ix = AscReadLramByte(iop_base,
6381 (ushort)(halt_q_addr +
6382 (ushort)ASC_SCSIQ_B_TARGET_IX));
6383 q_cntl = AscReadLramByte(iop_base,
6384 (ushort)(halt_q_addr + (ushort)ASC_SCSIQ_B_CNTL));
6385 tid_no = ASC_TIX_TO_TID(target_ix);
6386 target_id = (uchar)ASC_TID_TO_TARGET_ID(tid_no);
6387 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
6388 asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
6389 } else {
6390 asyn_sdtr = 0;
6391 }
6392 if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
6393 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
6394 AscSetChipSDTR(iop_base, 0, tid_no);
6395 boardp->sdtr_data[tid_no] = 0;
6396 }
6397 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6398 return;
6399 } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
6400 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
6401 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
6402 boardp->sdtr_data[tid_no] = asyn_sdtr;
6403 }
6404 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6405 return;
6406 } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
6407 AscMemWordCopyPtrFromLram(iop_base,
6408 ASCV_MSGIN_BEG,
6409 (uchar *)&ext_msg,
6410 sizeof(EXT_MSG) >> 1);
6411
6412 if (ext_msg.msg_type == EXTENDED_MESSAGE &&
6413 ext_msg.msg_req == EXTENDED_SDTR &&
6414 ext_msg.msg_len == MS_SDTR_LEN) {
6415 sdtr_accept = true;
6416 if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
6417
6418 sdtr_accept = false;
6419 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
6420 }
6421 if ((ext_msg.xfer_period <
6422 asc_dvc->sdtr_period_tbl[asc_dvc->min_sdtr_index])
6423 || (ext_msg.xfer_period >
6424 asc_dvc->sdtr_period_tbl[asc_dvc->
6425 max_sdtr_index])) {
6426 sdtr_accept = false;
6427 ext_msg.xfer_period =
6428 asc_dvc->sdtr_period_tbl[asc_dvc->
6429 min_sdtr_index];
6430 }
6431 if (sdtr_accept) {
6432 sdtr_data =
6433 AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
6434 ext_msg.req_ack_offset);
6435 if (sdtr_data == 0xFF) {
6436
6437 q_cntl |= QC_MSG_OUT;
6438 asc_dvc->init_sdtr &= ~target_id;
6439 asc_dvc->sdtr_done &= ~target_id;
6440 AscSetChipSDTR(iop_base, asyn_sdtr,
6441 tid_no);
6442 boardp->sdtr_data[tid_no] = asyn_sdtr;
6443 }
6444 }
6445 if (ext_msg.req_ack_offset == 0) {
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, tid_no);
6451 } else {
6452 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
6453 q_cntl &= ~QC_MSG_OUT;
6454 asc_dvc->sdtr_done |= target_id;
6455 asc_dvc->init_sdtr |= target_id;
6456 asc_dvc->pci_fix_asyn_xfer &=
6457 ~target_id;
6458 sdtr_data =
6459 AscCalSDTRData(asc_dvc,
6460 ext_msg.xfer_period,
6461 ext_msg.
6462 req_ack_offset);
6463 AscSetChipSDTR(iop_base, sdtr_data,
6464 tid_no);
6465 boardp->sdtr_data[tid_no] = sdtr_data;
6466 } else {
6467 q_cntl |= QC_MSG_OUT;
6468 AscMsgOutSDTR(asc_dvc,
6469 ext_msg.xfer_period,
6470 ext_msg.req_ack_offset);
6471 asc_dvc->pci_fix_asyn_xfer &=
6472 ~target_id;
6473 sdtr_data =
6474 AscCalSDTRData(asc_dvc,
6475 ext_msg.xfer_period,
6476 ext_msg.
6477 req_ack_offset);
6478 AscSetChipSDTR(iop_base, sdtr_data,
6479 tid_no);
6480 boardp->sdtr_data[tid_no] = sdtr_data;
6481 asc_dvc->sdtr_done |= target_id;
6482 asc_dvc->init_sdtr |= target_id;
6483 }
6484 }
6485
6486 AscWriteLramByte(iop_base,
6487 (ushort)(halt_q_addr +
6488 (ushort)ASC_SCSIQ_B_CNTL),
6489 q_cntl);
6490 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6491 return;
6492 } else if (ext_msg.msg_type == EXTENDED_MESSAGE &&
6493 ext_msg.msg_req == EXTENDED_WDTR &&
6494 ext_msg.msg_len == MS_WDTR_LEN) {
6495
6496 ext_msg.wdtr_width = 0;
6497 AscMemWordCopyPtrToLram(iop_base,
6498 ASCV_MSGOUT_BEG,
6499 (uchar *)&ext_msg,
6500 sizeof(EXT_MSG) >> 1);
6501 q_cntl |= QC_MSG_OUT;
6502 AscWriteLramByte(iop_base,
6503 (ushort)(halt_q_addr +
6504 (ushort)ASC_SCSIQ_B_CNTL),
6505 q_cntl);
6506 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6507 return;
6508 } else {
6509
6510 ext_msg.msg_type = MESSAGE_REJECT;
6511 AscMemWordCopyPtrToLram(iop_base,
6512 ASCV_MSGOUT_BEG,
6513 (uchar *)&ext_msg,
6514 sizeof(EXT_MSG) >> 1);
6515 q_cntl |= QC_MSG_OUT;
6516 AscWriteLramByte(iop_base,
6517 (ushort)(halt_q_addr +
6518 (ushort)ASC_SCSIQ_B_CNTL),
6519 q_cntl);
6520 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6521 return;
6522 }
6523 } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
6524
6525 q_cntl |= QC_REQ_SENSE;
6526
6527 if ((asc_dvc->init_sdtr & target_id) != 0) {
6528
6529 asc_dvc->sdtr_done &= ~target_id;
6530
6531 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
6532 q_cntl |= QC_MSG_OUT;
6533 AscMsgOutSDTR(asc_dvc,
6534 asc_dvc->
6535 sdtr_period_tbl[(sdtr_data >> 4) &
6536 (uchar)(asc_dvc->
6537 max_sdtr_index -
6538 1)],
6539 (uchar)(sdtr_data & (uchar)
6540 ASC_SYN_MAX_OFFSET));
6541 }
6542
6543 AscWriteLramByte(iop_base,
6544 (ushort)(halt_q_addr +
6545 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
6546
6547 tag_code = AscReadLramByte(iop_base,
6548 (ushort)(halt_q_addr + (ushort)
6549 ASC_SCSIQ_B_TAG_CODE));
6550 tag_code &= 0xDC;
6551 if ((asc_dvc->pci_fix_asyn_xfer & target_id)
6552 && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
6553 ) {
6554
6555 tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
6556 | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
6557
6558 }
6559 AscWriteLramByte(iop_base,
6560 (ushort)(halt_q_addr +
6561 (ushort)ASC_SCSIQ_B_TAG_CODE),
6562 tag_code);
6563
6564 q_status = AscReadLramByte(iop_base,
6565 (ushort)(halt_q_addr + (ushort)
6566 ASC_SCSIQ_B_STATUS));
6567 q_status |= (QS_READY | QS_BUSY);
6568 AscWriteLramByte(iop_base,
6569 (ushort)(halt_q_addr +
6570 (ushort)ASC_SCSIQ_B_STATUS),
6571 q_status);
6572
6573 scsi_busy = AscReadLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B);
6574 scsi_busy &= ~target_id;
6575 AscWriteLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B, scsi_busy);
6576
6577 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6578 return;
6579 } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
6580
6581 AscMemWordCopyPtrFromLram(iop_base,
6582 ASCV_MSGOUT_BEG,
6583 (uchar *)&out_msg,
6584 sizeof(EXT_MSG) >> 1);
6585
6586 if ((out_msg.msg_type == EXTENDED_MESSAGE) &&
6587 (out_msg.msg_len == MS_SDTR_LEN) &&
6588 (out_msg.msg_req == EXTENDED_SDTR)) {
6589
6590 asc_dvc->init_sdtr &= ~target_id;
6591 asc_dvc->sdtr_done &= ~target_id;
6592 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
6593 boardp->sdtr_data[tid_no] = asyn_sdtr;
6594 }
6595 q_cntl &= ~QC_MSG_OUT;
6596 AscWriteLramByte(iop_base,
6597 (ushort)(halt_q_addr +
6598 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
6599 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6600 return;
6601 } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
6602
6603 scsi_status = AscReadLramByte(iop_base,
6604 (ushort)((ushort)halt_q_addr +
6605 (ushort)
6606 ASC_SCSIQ_SCSI_STATUS));
6607 cur_dvc_qng =
6608 AscReadLramByte(iop_base,
6609 (ushort)((ushort)ASC_QADR_BEG +
6610 (ushort)target_ix));
6611 if ((cur_dvc_qng > 0) && (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
6612
6613 scsi_busy = AscReadLramByte(iop_base,
6614 (ushort)ASCV_SCSIBUSY_B);
6615 scsi_busy |= target_id;
6616 AscWriteLramByte(iop_base,
6617 (ushort)ASCV_SCSIBUSY_B, scsi_busy);
6618 asc_dvc->queue_full_or_busy |= target_id;
6619
6620 if (scsi_status == SAM_STAT_TASK_SET_FULL) {
6621 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
6622 cur_dvc_qng -= 1;
6623 asc_dvc->max_dvc_qng[tid_no] =
6624 cur_dvc_qng;
6625
6626 AscWriteLramByte(iop_base,
6627 (ushort)((ushort)
6628 ASCV_MAX_DVC_QNG_BEG
6629 + (ushort)
6630 tid_no),
6631 cur_dvc_qng);
6632
6633
6634
6635
6636
6637
6638 boardp->queue_full |= target_id;
6639 boardp->queue_full_cnt[tid_no] =
6640 cur_dvc_qng;
6641 }
6642 }
6643 }
6644 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6645 return;
6646 }
6647 return;
6648}
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660static void
6661DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
6662{
6663 int i;
6664 ushort word;
6665
6666 AscSetChipLramAddr(iop_base, s_addr);
6667 for (i = 0; i < 2 * words; i += 2) {
6668 if (i == 10) {
6669 continue;
6670 }
6671 word = inpw(iop_base + IOP_RAM_DATA);
6672 inbuf[i] = word & 0xff;
6673 inbuf[i + 1] = (word >> 8) & 0xff;
6674 }
6675 ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
6676}
6677
6678static uchar
6679_AscCopyLramScsiDoneQ(PortAddr iop_base,
6680 ushort q_addr,
6681 ASC_QDONE_INFO *scsiq, unsigned int max_dma_count)
6682{
6683 ushort _val;
6684 uchar sg_queue_cnt;
6685
6686 DvcGetQinfo(iop_base,
6687 q_addr + ASC_SCSIQ_DONE_INFO_BEG,
6688 (uchar *)scsiq,
6689 (sizeof(ASC_SCSIQ_2) + sizeof(ASC_SCSIQ_3)) / 2);
6690
6691 _val = AscReadLramWord(iop_base,
6692 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS));
6693 scsiq->q_status = (uchar)_val;
6694 scsiq->q_no = (uchar)(_val >> 8);
6695 _val = AscReadLramWord(iop_base,
6696 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_CNTL));
6697 scsiq->cntl = (uchar)_val;
6698 sg_queue_cnt = (uchar)(_val >> 8);
6699 _val = AscReadLramWord(iop_base,
6700 (ushort)(q_addr +
6701 (ushort)ASC_SCSIQ_B_SENSE_LEN));
6702 scsiq->sense_len = (uchar)_val;
6703 scsiq->extra_bytes = (uchar)(_val >> 8);
6704
6705
6706
6707
6708 scsiq->remain_bytes = (((u32)AscReadLramWord(iop_base,
6709 (ushort)(q_addr +
6710 (ushort)
6711 ASC_SCSIQ_W_ALT_DC1)))
6712 << 16);
6713
6714
6715
6716 scsiq->remain_bytes += AscReadLramWord(iop_base,
6717 (ushort)(q_addr + (ushort)
6718 ASC_SCSIQ_DW_REMAIN_XFER_CNT));
6719
6720 scsiq->remain_bytes &= max_dma_count;
6721 return sg_queue_cnt;
6722}
6723
6724
6725
6726
6727
6728
6729static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
6730{
6731 struct asc_board *boardp = asc_dvc_varp->drv_ptr;
6732 u32 srb_tag;
6733 struct scsi_cmnd *scp;
6734
6735 ASC_DBG(1, "asc_dvc_varp 0x%p, qdonep 0x%p\n", asc_dvc_varp, qdonep);
6736 ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
6737
6738
6739
6740
6741 srb_tag = qdonep->d2.srb_tag - 1;
6742 scp = scsi_host_find_tag(boardp->shost, srb_tag);
6743 if (!scp)
6744 return;
6745
6746 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
6747
6748 ASC_STATS(boardp->shost, callback);
6749
6750 dma_unmap_single(boardp->dev, scp->SCp.dma_handle,
6751 SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
6752
6753
6754
6755 switch (qdonep->d3.done_stat) {
6756 case QD_NO_ERROR:
6757 ASC_DBG(2, "QD_NO_ERROR\n");
6758 scp->result = 0;
6759
6760
6761
6762
6763
6764
6765
6766 if (scsi_bufflen(scp) != 0 && qdonep->remain_bytes != 0 &&
6767 qdonep->remain_bytes <= scsi_bufflen(scp)) {
6768 ASC_DBG(1, "underrun condition %u bytes\n",
6769 (unsigned)qdonep->remain_bytes);
6770 scsi_set_resid(scp, qdonep->remain_bytes);
6771 }
6772 break;
6773
6774 case QD_WITH_ERROR:
6775 ASC_DBG(2, "QD_WITH_ERROR\n");
6776 switch (qdonep->d3.host_stat) {
6777 case QHSTA_NO_ERROR:
6778 if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
6779 ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n");
6780 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
6781 SCSI_SENSE_BUFFERSIZE);
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
6795 STATUS_BYTE(qdonep->d3.scsi_stat);
6796 } else {
6797 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
6798 }
6799 break;
6800
6801 default:
6802
6803 ASC_DBG(1, "host_stat 0x%x\n", qdonep->d3.host_stat);
6804 scp->result = HOST_BYTE(DID_BAD_TARGET);
6805 break;
6806 }
6807 break;
6808
6809 case QD_ABORTED_BY_HOST:
6810 ASC_DBG(1, "QD_ABORTED_BY_HOST\n");
6811 scp->result =
6812 HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.
6813 scsi_msg) |
6814 STATUS_BYTE(qdonep->d3.scsi_stat);
6815 break;
6816
6817 default:
6818 ASC_DBG(1, "done_stat 0x%x\n", qdonep->d3.done_stat);
6819 scp->result =
6820 HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.
6821 scsi_msg) |
6822 STATUS_BYTE(qdonep->d3.scsi_stat);
6823 break;
6824 }
6825
6826
6827
6828
6829
6830
6831 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
6832 qdonep->d3.done_stat == QD_NO_ERROR &&
6833 qdonep->d3.host_stat == QHSTA_NO_ERROR) {
6834 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
6835 }
6836
6837 asc_scsi_done(scp);
6838}
6839
6840static int AscIsrQDone(ASC_DVC_VAR *asc_dvc)
6841{
6842 uchar next_qp;
6843 uchar n_q_used;
6844 uchar sg_list_qp;
6845 uchar sg_queue_cnt;
6846 uchar q_cnt;
6847 uchar done_q_tail;
6848 uchar tid_no;
6849 ASC_SCSI_BIT_ID_TYPE scsi_busy;
6850 ASC_SCSI_BIT_ID_TYPE target_id;
6851 PortAddr iop_base;
6852 ushort q_addr;
6853 ushort sg_q_addr;
6854 uchar cur_target_qng;
6855 ASC_QDONE_INFO scsiq_buf;
6856 ASC_QDONE_INFO *scsiq;
6857 bool false_overrun;
6858
6859 iop_base = asc_dvc->iop_base;
6860 n_q_used = 1;
6861 scsiq = (ASC_QDONE_INFO *)&scsiq_buf;
6862 done_q_tail = (uchar)AscGetVarDoneQTail(iop_base);
6863 q_addr = ASC_QNO_TO_QADDR(done_q_tail);
6864 next_qp = AscReadLramByte(iop_base,
6865 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_FWD));
6866 if (next_qp != ASC_QLINK_END) {
6867 AscPutVarDoneQTail(iop_base, next_qp);
6868 q_addr = ASC_QNO_TO_QADDR(next_qp);
6869 sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
6870 asc_dvc->max_dma_count);
6871 AscWriteLramByte(iop_base,
6872 (ushort)(q_addr +
6873 (ushort)ASC_SCSIQ_B_STATUS),
6874 (uchar)(scsiq->
6875 q_status & (uchar)~(QS_READY |
6876 QS_ABORTED)));
6877 tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
6878 target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
6879 if ((scsiq->cntl & QC_SG_HEAD) != 0) {
6880 sg_q_addr = q_addr;
6881 sg_list_qp = next_qp;
6882 for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
6883 sg_list_qp = AscReadLramByte(iop_base,
6884 (ushort)(sg_q_addr
6885 + (ushort)
6886 ASC_SCSIQ_B_FWD));
6887 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
6888 if (sg_list_qp == ASC_QLINK_END) {
6889 AscSetLibErrorCode(asc_dvc,
6890 ASCQ_ERR_SG_Q_LINKS);
6891 scsiq->d3.done_stat = QD_WITH_ERROR;
6892 scsiq->d3.host_stat =
6893 QHSTA_D_QDONE_SG_LIST_CORRUPTED;
6894 goto FATAL_ERR_QDONE;
6895 }
6896 AscWriteLramByte(iop_base,
6897 (ushort)(sg_q_addr + (ushort)
6898 ASC_SCSIQ_B_STATUS),
6899 QS_FREE);
6900 }
6901 n_q_used = sg_queue_cnt + 1;
6902 AscPutVarDoneQTail(iop_base, sg_list_qp);
6903 }
6904 if (asc_dvc->queue_full_or_busy & target_id) {
6905 cur_target_qng = AscReadLramByte(iop_base,
6906 (ushort)((ushort)
6907 ASC_QADR_BEG
6908 + (ushort)
6909 scsiq->d2.
6910 target_ix));
6911 if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
6912 scsi_busy = AscReadLramByte(iop_base, (ushort)
6913 ASCV_SCSIBUSY_B);
6914 scsi_busy &= ~target_id;
6915 AscWriteLramByte(iop_base,
6916 (ushort)ASCV_SCSIBUSY_B,
6917 scsi_busy);
6918 asc_dvc->queue_full_or_busy &= ~target_id;
6919 }
6920 }
6921 if (asc_dvc->cur_total_qng >= n_q_used) {
6922 asc_dvc->cur_total_qng -= n_q_used;
6923 if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
6924 asc_dvc->cur_dvc_qng[tid_no]--;
6925 }
6926 } else {
6927 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
6928 scsiq->d3.done_stat = QD_WITH_ERROR;
6929 goto FATAL_ERR_QDONE;
6930 }
6931 if ((scsiq->d2.srb_tag == 0UL) ||
6932 ((scsiq->q_status & QS_ABORTED) != 0)) {
6933 return (0x11);
6934 } else if (scsiq->q_status == QS_DONE) {
6935
6936
6937
6938
6939 false_overrun = false;
6940 if (scsiq->extra_bytes != 0) {
6941 scsiq->remain_bytes += scsiq->extra_bytes;
6942 }
6943 if (scsiq->d3.done_stat == QD_WITH_ERROR) {
6944 if (scsiq->d3.host_stat ==
6945 QHSTA_M_DATA_OVER_RUN) {
6946 if ((scsiq->
6947 cntl & (QC_DATA_IN | QC_DATA_OUT))
6948 == 0) {
6949 scsiq->d3.done_stat =
6950 QD_NO_ERROR;
6951 scsiq->d3.host_stat =
6952 QHSTA_NO_ERROR;
6953 } else if (false_overrun) {
6954 scsiq->d3.done_stat =
6955 QD_NO_ERROR;
6956 scsiq->d3.host_stat =
6957 QHSTA_NO_ERROR;
6958 }
6959 } else if (scsiq->d3.host_stat ==
6960 QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
6961 AscStopChip(iop_base);
6962 AscSetChipControl(iop_base,
6963 (uchar)(CC_SCSI_RESET
6964 | CC_HALT));
6965 udelay(60);
6966 AscSetChipControl(iop_base, CC_HALT);
6967 AscSetChipStatus(iop_base,
6968 CIW_CLR_SCSI_RESET_INT);
6969 AscSetChipStatus(iop_base, 0);
6970 AscSetChipControl(iop_base, 0);
6971 }
6972 }
6973 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
6974 asc_isr_callback(asc_dvc, scsiq);
6975 } else {
6976 if ((AscReadLramByte(iop_base,
6977 (ushort)(q_addr + (ushort)
6978 ASC_SCSIQ_CDB_BEG))
6979 == START_STOP)) {
6980 asc_dvc->unit_not_ready &= ~target_id;
6981 if (scsiq->d3.done_stat != QD_NO_ERROR) {
6982 asc_dvc->start_motor &=
6983 ~target_id;
6984 }
6985 }
6986 }
6987 return (1);
6988 } else {
6989 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
6990 FATAL_ERR_QDONE:
6991 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
6992 asc_isr_callback(asc_dvc, scsiq);
6993 }
6994 return (0x80);
6995 }
6996 }
6997 return (0);
6998}
6999
7000static int AscISR(ASC_DVC_VAR *asc_dvc)
7001{
7002 ASC_CS_TYPE chipstat;
7003 PortAddr iop_base;
7004 ushort saved_ram_addr;
7005 uchar ctrl_reg;
7006 uchar saved_ctrl_reg;
7007 int int_pending;
7008 int status;
7009 uchar host_flag;
7010
7011 iop_base = asc_dvc->iop_base;
7012 int_pending = ASC_FALSE;
7013
7014 if (AscIsIntPending(iop_base) == 0)
7015 return int_pending;
7016
7017 if ((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0) {
7018 return ASC_ERROR;
7019 }
7020 if (asc_dvc->in_critical_cnt != 0) {
7021 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
7022 return ASC_ERROR;
7023 }
7024 if (asc_dvc->is_in_int) {
7025 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
7026 return ASC_ERROR;
7027 }
7028 asc_dvc->is_in_int = true;
7029 ctrl_reg = AscGetChipControl(iop_base);
7030 saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
7031 CC_SINGLE_STEP | CC_DIAG | CC_TEST));
7032 chipstat = AscGetChipStatus(iop_base);
7033 if (chipstat & CSW_SCSI_RESET_LATCH) {
7034 if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
7035 int i = 10;
7036 int_pending = ASC_TRUE;
7037 asc_dvc->sdtr_done = 0;
7038 saved_ctrl_reg &= (uchar)(~CC_HALT);
7039 while ((AscGetChipStatus(iop_base) &
7040 CSW_SCSI_RESET_ACTIVE) && (i-- > 0)) {
7041 mdelay(100);
7042 }
7043 AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
7044 AscSetChipControl(iop_base, CC_HALT);
7045 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
7046 AscSetChipStatus(iop_base, 0);
7047 chipstat = AscGetChipStatus(iop_base);
7048 }
7049 }
7050 saved_ram_addr = AscGetChipLramAddr(iop_base);
7051 host_flag = AscReadLramByte(iop_base,
7052 ASCV_HOST_FLAG_B) &
7053 (uchar)(~ASC_HOST_FLAG_IN_ISR);
7054 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
7055 (uchar)(host_flag | (uchar)ASC_HOST_FLAG_IN_ISR));
7056 if ((chipstat & CSW_INT_PENDING) || (int_pending)) {
7057 AscAckInterrupt(iop_base);
7058 int_pending = ASC_TRUE;
7059 if ((chipstat & CSW_HALTED) && (ctrl_reg & CC_SINGLE_STEP)) {
7060 AscIsrChipHalted(asc_dvc);
7061 saved_ctrl_reg &= (uchar)(~CC_HALT);
7062 } else {
7063 if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
7064 while (((status =
7065 AscIsrQDone(asc_dvc)) & 0x01) != 0) {
7066 }
7067 } else {
7068 do {
7069 if ((status =
7070 AscIsrQDone(asc_dvc)) == 1) {
7071 break;
7072 }
7073 } while (status == 0x11);
7074 }
7075 if ((status & 0x80) != 0)
7076 int_pending = ASC_ERROR;
7077 }
7078 }
7079 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
7080 AscSetChipLramAddr(iop_base, saved_ram_addr);
7081 AscSetChipControl(iop_base, saved_ctrl_reg);
7082 asc_dvc->is_in_int = false;
7083 return int_pending;
7084}
7085
7086
7087
7088
7089
7090
7091
7092
7093
7094
7095static int advansys_reset(struct scsi_cmnd *scp)
7096{
7097 struct Scsi_Host *shost = scp->device->host;
7098 struct asc_board *boardp = shost_priv(shost);
7099 unsigned long flags;
7100 int status;
7101 int ret = SUCCESS;
7102
7103 ASC_DBG(1, "0x%p\n", scp);
7104
7105 ASC_STATS(shost, reset);
7106
7107 scmd_printk(KERN_INFO, scp, "SCSI host reset started...\n");
7108
7109 if (ASC_NARROW_BOARD(boardp)) {
7110 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
7111
7112
7113 ASC_DBG(1, "before AscInitAsc1000Driver()\n");
7114 status = AscInitAsc1000Driver(asc_dvc);
7115
7116
7117 if (asc_dvc->err_code || !asc_dvc->overrun_dma) {
7118 scmd_printk(KERN_INFO, scp, "SCSI host reset error: "
7119 "0x%x, status: 0x%x\n", asc_dvc->err_code,
7120 status);
7121 ret = FAILED;
7122 } else if (status) {
7123 scmd_printk(KERN_INFO, scp, "SCSI host reset warning: "
7124 "0x%x\n", status);
7125 } else {
7126 scmd_printk(KERN_INFO, scp, "SCSI host reset "
7127 "successful\n");
7128 }
7129
7130 ASC_DBG(1, "after AscInitAsc1000Driver()\n");
7131 } else {
7132
7133
7134
7135
7136 ADV_DVC_VAR *adv_dvc = &boardp->dvc_var.adv_dvc_var;
7137
7138
7139
7140
7141 ASC_DBG(1, "before AdvResetChipAndSB()\n");
7142 switch (AdvResetChipAndSB(adv_dvc)) {
7143 case ASC_TRUE:
7144 scmd_printk(KERN_INFO, scp, "SCSI host reset "
7145 "successful\n");
7146 break;
7147 case ASC_FALSE:
7148 default:
7149 scmd_printk(KERN_INFO, scp, "SCSI host reset error\n");
7150 ret = FAILED;
7151 break;
7152 }
7153 spin_lock_irqsave(shost->host_lock, flags);
7154 AdvISR(adv_dvc);
7155 spin_unlock_irqrestore(shost->host_lock, flags);
7156 }
7157
7158 ASC_DBG(1, "ret %d\n", ret);
7159
7160 return ret;
7161}
7162
7163
7164
7165
7166
7167
7168
7169
7170
7171
7172
7173
7174static int
7175advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
7176 sector_t capacity, int ip[])
7177{
7178 struct asc_board *boardp = shost_priv(sdev->host);
7179
7180 ASC_DBG(1, "begin\n");
7181 ASC_STATS(sdev->host, biosparam);
7182 if (ASC_NARROW_BOARD(boardp)) {
7183 if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
7184 ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) {
7185 ip[0] = 255;
7186 ip[1] = 63;
7187 } else {
7188 ip[0] = 64;
7189 ip[1] = 32;
7190 }
7191 } else {
7192 if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
7193 BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) {
7194 ip[0] = 255;
7195 ip[1] = 63;
7196 } else {
7197 ip[0] = 64;
7198 ip[1] = 32;
7199 }
7200 }
7201 ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
7202 ASC_DBG(1, "end\n");
7203 return 0;
7204}
7205
7206
7207
7208
7209
7210
7211static irqreturn_t advansys_interrupt(int irq, void *dev_id)
7212{
7213 struct Scsi_Host *shost = dev_id;
7214 struct asc_board *boardp = shost_priv(shost);
7215 irqreturn_t result = IRQ_NONE;
7216 unsigned long flags;
7217
7218 ASC_DBG(2, "boardp 0x%p\n", boardp);
7219 spin_lock_irqsave(shost->host_lock, flags);
7220 if (ASC_NARROW_BOARD(boardp)) {
7221 if (AscIsIntPending(shost->io_port)) {
7222 result = IRQ_HANDLED;
7223 ASC_STATS(shost, interrupt);
7224 ASC_DBG(1, "before AscISR()\n");
7225 AscISR(&boardp->dvc_var.asc_dvc_var);
7226 }
7227 } else {
7228 ASC_DBG(1, "before AdvISR()\n");
7229 if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
7230 result = IRQ_HANDLED;
7231 ASC_STATS(shost, interrupt);
7232 }
7233 }
7234 spin_unlock_irqrestore(shost->host_lock, flags);
7235
7236 ASC_DBG(1, "end\n");
7237 return result;
7238}
7239
7240static bool AscHostReqRiscHalt(PortAddr iop_base)
7241{
7242 int count = 0;
7243 bool sta = false;
7244 uchar saved_stop_code;
7245
7246 if (AscIsChipHalted(iop_base))
7247 return true;
7248 saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
7249 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
7250 ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP);
7251 do {
7252 if (AscIsChipHalted(iop_base)) {
7253 sta = true;
7254 break;
7255 }
7256 mdelay(100);
7257 } while (count++ < 20);
7258 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
7259 return sta;
7260}
7261
7262static bool
7263AscSetRunChipSynRegAtID(PortAddr iop_base, uchar tid_no, uchar sdtr_data)
7264{
7265 bool sta = false;
7266
7267 if (AscHostReqRiscHalt(iop_base)) {
7268 sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
7269 AscStartChip(iop_base);
7270 }
7271 return sta;
7272}
7273
7274static void AscAsyncFix(ASC_DVC_VAR *asc_dvc, struct scsi_device *sdev)
7275{
7276 char type = sdev->type;
7277 ASC_SCSI_BIT_ID_TYPE tid_bits = 1 << sdev->id;
7278
7279 if (!(asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN))
7280 return;
7281 if (asc_dvc->init_sdtr & tid_bits)
7282 return;
7283
7284 if ((type == TYPE_ROM) && (strncmp(sdev->vendor, "HP ", 3) == 0))
7285 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
7286
7287 asc_dvc->pci_fix_asyn_xfer |= tid_bits;
7288 if ((type == TYPE_PROCESSOR) || (type == TYPE_SCANNER) ||
7289 (type == TYPE_ROM) || (type == TYPE_TAPE))
7290 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
7291
7292 if (asc_dvc->pci_fix_asyn_xfer & tid_bits)
7293 AscSetRunChipSynRegAtID(asc_dvc->iop_base, sdev->id,
7294 ASYN_SDTR_DATA_FIX_PCI_REV_AB);
7295}
7296
7297static void
7298advansys_narrow_slave_configure(struct scsi_device *sdev, ASC_DVC_VAR *asc_dvc)
7299{
7300 ASC_SCSI_BIT_ID_TYPE tid_bit = 1 << sdev->id;
7301 ASC_SCSI_BIT_ID_TYPE orig_use_tagged_qng = asc_dvc->use_tagged_qng;
7302
7303 if (sdev->lun == 0) {
7304 ASC_SCSI_BIT_ID_TYPE orig_init_sdtr = asc_dvc->init_sdtr;
7305 if ((asc_dvc->cfg->sdtr_enable & tid_bit) && sdev->sdtr) {
7306 asc_dvc->init_sdtr |= tid_bit;
7307 } else {
7308 asc_dvc->init_sdtr &= ~tid_bit;
7309 }
7310
7311 if (orig_init_sdtr != asc_dvc->init_sdtr)
7312 AscAsyncFix(asc_dvc, sdev);
7313 }
7314
7315 if (sdev->tagged_supported) {
7316 if (asc_dvc->cfg->cmd_qng_enabled & tid_bit) {
7317 if (sdev->lun == 0) {
7318 asc_dvc->cfg->can_tagged_qng |= tid_bit;
7319 asc_dvc->use_tagged_qng |= tid_bit;
7320 }
7321 scsi_change_queue_depth(sdev,
7322 asc_dvc->max_dvc_qng[sdev->id]);
7323 }
7324 } else {
7325 if (sdev->lun == 0) {
7326 asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
7327 asc_dvc->use_tagged_qng &= ~tid_bit;
7328 }
7329 }
7330
7331 if ((sdev->lun == 0) &&
7332 (orig_use_tagged_qng != asc_dvc->use_tagged_qng)) {
7333 AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
7334 asc_dvc->cfg->disc_enable);
7335 AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
7336 asc_dvc->use_tagged_qng);
7337 AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
7338 asc_dvc->cfg->can_tagged_qng);
7339
7340 asc_dvc->max_dvc_qng[sdev->id] =
7341 asc_dvc->cfg->max_tag_qng[sdev->id];
7342 AscWriteLramByte(asc_dvc->iop_base,
7343 (ushort)(ASCV_MAX_DVC_QNG_BEG + sdev->id),
7344 asc_dvc->max_dvc_qng[sdev->id]);
7345 }
7346}
7347
7348
7349
7350
7351
7352
7353
7354
7355static void
7356advansys_wide_enable_wdtr(AdvPortAddr iop_base, unsigned short tidmask)
7357{
7358 unsigned short cfg_word;
7359 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
7360 if ((cfg_word & tidmask) != 0)
7361 return;
7362
7363 cfg_word |= tidmask;
7364 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
7365
7366
7367
7368
7369
7370
7371
7372 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
7373 cfg_word &= ~tidmask;
7374 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
7375 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
7376 cfg_word &= ~tidmask;
7377 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
7378}
7379
7380
7381
7382
7383
7384
7385
7386
7387static void
7388advansys_wide_enable_sdtr(AdvPortAddr iop_base, unsigned short tidmask)
7389{
7390 unsigned short cfg_word;
7391 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
7392 if ((cfg_word & tidmask) != 0)
7393 return;
7394
7395 cfg_word |= tidmask;
7396 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
7397
7398
7399
7400
7401
7402 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
7403 cfg_word &= ~tidmask;
7404 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
7405}
7406
7407
7408
7409
7410
7411
7412
7413
7414
7415static void advansys_wide_enable_ppr(ADV_DVC_VAR *adv_dvc,
7416 AdvPortAddr iop_base, unsigned short tidmask)
7417{
7418 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
7419 adv_dvc->ppr_able |= tidmask;
7420 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
7421}
7422
7423static void
7424advansys_wide_slave_configure(struct scsi_device *sdev, ADV_DVC_VAR *adv_dvc)
7425{
7426 AdvPortAddr iop_base = adv_dvc->iop_base;
7427 unsigned short tidmask = 1 << sdev->id;
7428
7429 if (sdev->lun == 0) {
7430
7431
7432
7433
7434
7435
7436 if ((adv_dvc->wdtr_able & tidmask) && sdev->wdtr)
7437 advansys_wide_enable_wdtr(iop_base, tidmask);
7438 if ((adv_dvc->sdtr_able & tidmask) && sdev->sdtr)
7439 advansys_wide_enable_sdtr(iop_base, tidmask);
7440 if (adv_dvc->chip_type == ADV_CHIP_ASC38C1600 && sdev->ppr)
7441 advansys_wide_enable_ppr(adv_dvc, iop_base, tidmask);
7442
7443
7444
7445
7446
7447
7448
7449 if ((adv_dvc->tagqng_able & tidmask) &&
7450 sdev->tagged_supported) {
7451 unsigned short cfg_word;
7452 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
7453 cfg_word |= tidmask;
7454 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
7455 cfg_word);
7456 AdvWriteByteLram(iop_base,
7457 ASC_MC_NUMBER_OF_MAX_CMD + sdev->id,
7458 adv_dvc->max_dvc_qng);
7459 }
7460 }
7461
7462 if ((adv_dvc->tagqng_able & tidmask) && sdev->tagged_supported)
7463 scsi_change_queue_depth(sdev, adv_dvc->max_dvc_qng);
7464}
7465
7466
7467
7468
7469
7470static int advansys_slave_configure(struct scsi_device *sdev)
7471{
7472 struct asc_board *boardp = shost_priv(sdev->host);
7473
7474 if (ASC_NARROW_BOARD(boardp))
7475 advansys_narrow_slave_configure(sdev,
7476 &boardp->dvc_var.asc_dvc_var);
7477 else
7478 advansys_wide_slave_configure(sdev,
7479 &boardp->dvc_var.adv_dvc_var);
7480
7481 return 0;
7482}
7483
7484static __le32 asc_get_sense_buffer_dma(struct scsi_cmnd *scp)
7485{
7486 struct asc_board *board = shost_priv(scp->device->host);
7487
7488 scp->SCp.dma_handle = dma_map_single(board->dev, scp->sense_buffer,
7489 SCSI_SENSE_BUFFERSIZE,
7490 DMA_FROM_DEVICE);
7491 if (dma_mapping_error(board->dev, scp->SCp.dma_handle)) {
7492 ASC_DBG(1, "failed to map sense buffer\n");
7493 return 0;
7494 }
7495 return cpu_to_le32(scp->SCp.dma_handle);
7496}
7497
7498static int asc_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,
7499 struct asc_scsi_q *asc_scsi_q)
7500{
7501 struct asc_dvc_var *asc_dvc = &boardp->dvc_var.asc_dvc_var;
7502 int use_sg;
7503 u32 srb_tag;
7504
7505 memset(asc_scsi_q, 0, sizeof(*asc_scsi_q));
7506
7507
7508
7509
7510
7511 srb_tag = scp->request->tag + 1;
7512 asc_scsi_q->q2.srb_tag = srb_tag;
7513
7514
7515
7516
7517 asc_scsi_q->cdbptr = &scp->cmnd[0];
7518 asc_scsi_q->q2.cdb_len = scp->cmd_len;
7519 asc_scsi_q->q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
7520 asc_scsi_q->q1.target_lun = scp->device->lun;
7521 asc_scsi_q->q2.target_ix =
7522 ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
7523 asc_scsi_q->q1.sense_addr = asc_get_sense_buffer_dma(scp);
7524 asc_scsi_q->q1.sense_len = SCSI_SENSE_BUFFERSIZE;
7525 if (!asc_scsi_q->q1.sense_addr)
7526 return ASC_BUSY;
7527
7528
7529
7530
7531
7532
7533
7534
7535
7536
7537
7538
7539 if ((asc_dvc->cur_dvc_qng[scp->device->id] > 0) &&
7540 (boardp->reqcnt[scp->device->id] % 255) == 0) {
7541 asc_scsi_q->q2.tag_code = ORDERED_QUEUE_TAG;
7542 } else {
7543 asc_scsi_q->q2.tag_code = SIMPLE_QUEUE_TAG;
7544 }
7545
7546
7547 use_sg = scsi_dma_map(scp);
7548 if (use_sg < 0) {
7549 ASC_DBG(1, "failed to map sglist\n");
7550 return ASC_BUSY;
7551 } else if (use_sg > 0) {
7552 int sgcnt;
7553 struct scatterlist *slp;
7554 struct asc_sg_head *asc_sg_head;
7555
7556 if (use_sg > scp->device->host->sg_tablesize) {
7557 scmd_printk(KERN_ERR, scp, "use_sg %d > "
7558 "sg_tablesize %d\n", use_sg,
7559 scp->device->host->sg_tablesize);
7560 scsi_dma_unmap(scp);
7561 scp->result = HOST_BYTE(DID_ERROR);
7562 return ASC_ERROR;
7563 }
7564
7565 asc_sg_head = kzalloc(sizeof(asc_scsi_q->sg_head) +
7566 use_sg * sizeof(struct asc_sg_list), GFP_ATOMIC);
7567 if (!asc_sg_head) {
7568 scsi_dma_unmap(scp);
7569 scp->result = HOST_BYTE(DID_SOFT_ERROR);
7570 return ASC_ERROR;
7571 }
7572
7573 asc_scsi_q->q1.cntl |= QC_SG_HEAD;
7574 asc_scsi_q->sg_head = asc_sg_head;
7575 asc_scsi_q->q1.data_cnt = 0;
7576 asc_scsi_q->q1.data_addr = 0;
7577
7578 asc_sg_head->entry_cnt = asc_scsi_q->q1.sg_queue_cnt = use_sg;
7579 ASC_STATS_ADD(scp->device->host, xfer_elem,
7580 asc_sg_head->entry_cnt);
7581
7582
7583
7584
7585 scsi_for_each_sg(scp, slp, use_sg, sgcnt) {
7586 asc_sg_head->sg_list[sgcnt].addr =
7587 cpu_to_le32(sg_dma_address(slp));
7588 asc_sg_head->sg_list[sgcnt].bytes =
7589 cpu_to_le32(sg_dma_len(slp));
7590 ASC_STATS_ADD(scp->device->host, xfer_sect,
7591 DIV_ROUND_UP(sg_dma_len(slp), 512));
7592 }
7593 }
7594
7595 ASC_STATS(scp->device->host, xfer_cnt);
7596
7597 ASC_DBG_PRT_ASC_SCSI_Q(2, asc_scsi_q);
7598 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
7599
7600 return ASC_NOERROR;
7601}
7602
7603
7604
7605
7606
7607
7608
7609
7610
7611
7612
7613
7614
7615static int
7616adv_get_sglist(struct asc_board *boardp, adv_req_t *reqp,
7617 ADV_SCSI_REQ_Q *scsiqp, struct scsi_cmnd *scp, int use_sg)
7618{
7619 adv_sgblk_t *sgblkp, *prev_sgblkp;
7620 struct scatterlist *slp;
7621 int sg_elem_cnt;
7622 ADV_SG_BLOCK *sg_block, *prev_sg_block;
7623 dma_addr_t sgblk_paddr;
7624 int i;
7625
7626 slp = scsi_sglist(scp);
7627 sg_elem_cnt = use_sg;
7628 prev_sgblkp = NULL;
7629 prev_sg_block = NULL;
7630 reqp->sgblkp = NULL;
7631
7632 for (;;) {
7633
7634
7635
7636
7637
7638 sgblkp = dma_pool_alloc(boardp->adv_sgblk_pool, GFP_ATOMIC,
7639 &sgblk_paddr);
7640 if (!sgblkp) {
7641 ASC_DBG(1, "no free adv_sgblk_t\n");
7642 ASC_STATS(scp->device->host, adv_build_nosg);
7643
7644
7645
7646
7647
7648 while ((sgblkp = reqp->sgblkp) != NULL) {
7649
7650 reqp->sgblkp = sgblkp->next_sgblkp;
7651 sgblkp->next_sgblkp = NULL;
7652 dma_pool_free(boardp->adv_sgblk_pool, sgblkp,
7653 sgblkp->sg_addr);
7654 }
7655 return ASC_BUSY;
7656 }
7657
7658 sgblkp->sg_addr = sgblk_paddr;
7659 sgblkp->next_sgblkp = NULL;
7660 sg_block = &sgblkp->sg_block;
7661
7662
7663
7664
7665
7666 if (reqp->sgblkp == NULL) {
7667
7668 reqp->sgblkp = sgblkp;
7669
7670
7671
7672
7673
7674 scsiqp->sg_list_ptr = sg_block;
7675 scsiqp->sg_real_addr = cpu_to_le32(sgblk_paddr);
7676 } else {
7677
7678 prev_sgblkp->next_sgblkp = sgblkp;
7679
7680
7681
7682
7683
7684 prev_sg_block->sg_ptr = cpu_to_le32(sgblk_paddr);
7685 }
7686
7687 for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) {
7688 sg_block->sg_list[i].sg_addr =
7689 cpu_to_le32(sg_dma_address(slp));
7690 sg_block->sg_list[i].sg_count =
7691 cpu_to_le32(sg_dma_len(slp));
7692 ASC_STATS_ADD(scp->device->host, xfer_sect,
7693 DIV_ROUND_UP(sg_dma_len(slp), 512));
7694
7695 if (--sg_elem_cnt == 0) {
7696
7697
7698
7699 sg_block->sg_cnt = i + 1;
7700 sg_block->sg_ptr = 0L;
7701 return ADV_SUCCESS;
7702 }
7703 slp = sg_next(slp);
7704 }
7705 sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
7706 prev_sg_block = sg_block;
7707 prev_sgblkp = sgblkp;
7708 }
7709}
7710
7711
7712
7713
7714
7715
7716
7717
7718
7719
7720
7721static int
7722adv_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,
7723 adv_req_t **adv_reqpp)
7724{
7725 u32 srb_tag = scp->request->tag;
7726 adv_req_t *reqp;
7727 ADV_SCSI_REQ_Q *scsiqp;
7728 int ret;
7729 int use_sg;
7730 dma_addr_t sense_addr;
7731
7732
7733
7734
7735
7736 reqp = &boardp->adv_reqp[srb_tag];
7737 if (reqp->cmndp && reqp->cmndp != scp ) {
7738 ASC_DBG(1, "no free adv_req_t\n");
7739 ASC_STATS(scp->device->host, adv_build_noreq);
7740 return ASC_BUSY;
7741 }
7742
7743 reqp->req_addr = boardp->adv_reqp_addr + (srb_tag * sizeof(adv_req_t));
7744
7745 scsiqp = &reqp->scsi_req_q;
7746
7747
7748
7749
7750 scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
7751
7752
7753
7754
7755 scsiqp->srb_tag = srb_tag;
7756
7757
7758
7759
7760 reqp->cmndp = scp;
7761 scp->host_scribble = (void *)reqp;
7762
7763
7764
7765
7766
7767
7768 scsiqp->cdb_len = scp->cmd_len;
7769
7770 memcpy(scsiqp->cdb, scp->cmnd, scp->cmd_len < 12 ? scp->cmd_len : 12);
7771
7772 if (scp->cmd_len > 12) {
7773 int cdb16_len = scp->cmd_len - 12;
7774
7775 memcpy(scsiqp->cdb16, &scp->cmnd[12], cdb16_len);
7776 }
7777
7778 scsiqp->target_id = scp->device->id;
7779 scsiqp->target_lun = scp->device->lun;
7780
7781 sense_addr = dma_map_single(boardp->dev, scp->sense_buffer,
7782 SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
7783 if (dma_mapping_error(boardp->dev, sense_addr)) {
7784 ASC_DBG(1, "failed to map sense buffer\n");
7785 ASC_STATS(scp->device->host, adv_build_noreq);
7786 return ASC_BUSY;
7787 }
7788 scsiqp->sense_addr = cpu_to_le32(sense_addr);
7789 scsiqp->sense_len = SCSI_SENSE_BUFFERSIZE;
7790
7791
7792
7793 use_sg = scsi_dma_map(scp);
7794 if (use_sg < 0) {
7795 ASC_DBG(1, "failed to map SG list\n");
7796 ASC_STATS(scp->device->host, adv_build_noreq);
7797 return ASC_BUSY;
7798 } else if (use_sg == 0) {
7799
7800 reqp->sgblkp = NULL;
7801 scsiqp->data_cnt = 0;
7802
7803 scsiqp->data_addr = 0;
7804 scsiqp->sg_list_ptr = NULL;
7805 scsiqp->sg_real_addr = 0;
7806 } else {
7807 if (use_sg > ADV_MAX_SG_LIST) {
7808 scmd_printk(KERN_ERR, scp, "use_sg %d > "
7809 "ADV_MAX_SG_LIST %d\n", use_sg,
7810 scp->device->host->sg_tablesize);
7811 scsi_dma_unmap(scp);
7812 scp->result = HOST_BYTE(DID_ERROR);
7813 reqp->cmndp = NULL;
7814 scp->host_scribble = NULL;
7815
7816 return ASC_ERROR;
7817 }
7818
7819 scsiqp->data_cnt = cpu_to_le32(scsi_bufflen(scp));
7820
7821 ret = adv_get_sglist(boardp, reqp, scsiqp, scp, use_sg);
7822 if (ret != ADV_SUCCESS) {
7823 scsi_dma_unmap(scp);
7824 scp->result = HOST_BYTE(DID_ERROR);
7825 reqp->cmndp = NULL;
7826 scp->host_scribble = NULL;
7827
7828 return ret;
7829 }
7830
7831 ASC_STATS_ADD(scp->device->host, xfer_elem, use_sg);
7832 }
7833
7834 ASC_STATS(scp->device->host, xfer_cnt);
7835
7836 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
7837 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
7838
7839 *adv_reqpp = reqp;
7840
7841 return ASC_NOERROR;
7842}
7843
7844static int AscSgListToQueue(int sg_list)
7845{
7846 int n_sg_list_qs;
7847
7848 n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
7849 if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
7850 n_sg_list_qs++;
7851 return n_sg_list_qs + 1;
7852}
7853
7854static uint
7855AscGetNumOfFreeQueue(ASC_DVC_VAR *asc_dvc, uchar target_ix, uchar n_qs)
7856{
7857 uint cur_used_qs;
7858 uint cur_free_qs;
7859 ASC_SCSI_BIT_ID_TYPE target_id;
7860 uchar tid_no;
7861
7862 target_id = ASC_TIX_TO_TARGET_ID(target_ix);
7863 tid_no = ASC_TIX_TO_TID(target_ix);
7864 if ((asc_dvc->unit_not_ready & target_id) ||
7865 (asc_dvc->queue_full_or_busy & target_id)) {
7866 return 0;
7867 }
7868 if (n_qs == 1) {
7869 cur_used_qs = (uint) asc_dvc->cur_total_qng +
7870 (uint) asc_dvc->last_q_shortage + (uint) ASC_MIN_FREE_Q;
7871 } else {
7872 cur_used_qs = (uint) asc_dvc->cur_total_qng +
7873 (uint) ASC_MIN_FREE_Q;
7874 }
7875 if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
7876 cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
7877 if (asc_dvc->cur_dvc_qng[tid_no] >=
7878 asc_dvc->max_dvc_qng[tid_no]) {
7879 return 0;
7880 }
7881 return cur_free_qs;
7882 }
7883 if (n_qs > 1) {
7884 if ((n_qs > asc_dvc->last_q_shortage)
7885 && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
7886 asc_dvc->last_q_shortage = n_qs;
7887 }
7888 }
7889 return 0;
7890}
7891
7892static uchar AscAllocFreeQueue(PortAddr iop_base, uchar free_q_head)
7893{
7894 ushort q_addr;
7895 uchar next_qp;
7896 uchar q_status;
7897
7898 q_addr = ASC_QNO_TO_QADDR(free_q_head);
7899 q_status = (uchar)AscReadLramByte(iop_base,
7900 (ushort)(q_addr +
7901 ASC_SCSIQ_B_STATUS));
7902 next_qp = AscReadLramByte(iop_base, (ushort)(q_addr + ASC_SCSIQ_B_FWD));
7903 if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END))
7904 return next_qp;
7905 return ASC_QLINK_END;
7906}
7907
7908static uchar
7909AscAllocMultipleFreeQueue(PortAddr iop_base, uchar free_q_head, uchar n_free_q)
7910{
7911 uchar i;
7912
7913 for (i = 0; i < n_free_q; i++) {
7914 free_q_head = AscAllocFreeQueue(iop_base, free_q_head);
7915 if (free_q_head == ASC_QLINK_END)
7916 break;
7917 }
7918 return free_q_head;
7919}
7920
7921
7922
7923
7924
7925
7926
7927
7928
7929
7930
7931static void
7932DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
7933{
7934 int i;
7935
7936 ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
7937 AscSetChipLramAddr(iop_base, s_addr);
7938 for (i = 0; i < 2 * words; i += 2) {
7939 if (i == 4 || i == 20) {
7940 continue;
7941 }
7942 outpw(iop_base + IOP_RAM_DATA,
7943 ((ushort)outbuf[i + 1] << 8) | outbuf[i]);
7944 }
7945}
7946
7947static int AscPutReadyQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
7948{
7949 ushort q_addr;
7950 uchar tid_no;
7951 uchar sdtr_data;
7952 uchar syn_period_ix;
7953 uchar syn_offset;
7954 PortAddr iop_base;
7955
7956 iop_base = asc_dvc->iop_base;
7957 if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
7958 ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
7959 tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
7960 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
7961 syn_period_ix =
7962 (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
7963 syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
7964 AscMsgOutSDTR(asc_dvc,
7965 asc_dvc->sdtr_period_tbl[syn_period_ix],
7966 syn_offset);
7967 scsiq->q1.cntl |= QC_MSG_OUT;
7968 }
7969 q_addr = ASC_QNO_TO_QADDR(q_no);
7970 if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
7971 scsiq->q2.tag_code &= ~SIMPLE_QUEUE_TAG;
7972 }
7973 scsiq->q1.status = QS_FREE;
7974 AscMemWordCopyPtrToLram(iop_base,
7975 q_addr + ASC_SCSIQ_CDB_BEG,
7976 (uchar *)scsiq->cdbptr, scsiq->q2.cdb_len >> 1);
7977
7978 DvcPutScsiQ(iop_base,
7979 q_addr + ASC_SCSIQ_CPY_BEG,
7980 (uchar *)&scsiq->q1.cntl,
7981 ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
7982 AscWriteLramWord(iop_base,
7983 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS),
7984 (ushort)(((ushort)scsiq->q1.
7985 q_no << 8) | (ushort)QS_READY));
7986 return 1;
7987}
7988
7989static int
7990AscPutReadySgListQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
7991{
7992 int sta;
7993 int i;
7994 ASC_SG_HEAD *sg_head;
7995 ASC_SG_LIST_Q scsi_sg_q;
7996 __le32 saved_data_addr;
7997 __le32 saved_data_cnt;
7998 PortAddr iop_base;
7999 ushort sg_list_dwords;
8000 ushort sg_index;
8001 ushort sg_entry_cnt;
8002 ushort q_addr;
8003 uchar next_qp;
8004
8005 iop_base = asc_dvc->iop_base;
8006 sg_head = scsiq->sg_head;
8007 saved_data_addr = scsiq->q1.data_addr;
8008 saved_data_cnt = scsiq->q1.data_cnt;
8009 scsiq->q1.data_addr = cpu_to_le32(sg_head->sg_list[0].addr);
8010 scsiq->q1.data_cnt = cpu_to_le32(sg_head->sg_list[0].bytes);
8011
8012
8013
8014
8015
8016 sg_entry_cnt = sg_head->entry_cnt - 1;
8017
8018 if (sg_entry_cnt != 0) {
8019 scsiq->q1.cntl |= QC_SG_HEAD;
8020 q_addr = ASC_QNO_TO_QADDR(q_no);
8021 sg_index = 1;
8022 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
8023 scsi_sg_q.sg_head_qp = q_no;
8024 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
8025 for (i = 0; i < sg_head->queue_cnt; i++) {
8026 scsi_sg_q.seq_no = i + 1;
8027 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
8028 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
8029 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
8030 if (i == 0) {
8031 scsi_sg_q.sg_list_cnt =
8032 ASC_SG_LIST_PER_Q;
8033 scsi_sg_q.sg_cur_list_cnt =
8034 ASC_SG_LIST_PER_Q;
8035 } else {
8036 scsi_sg_q.sg_list_cnt =
8037 ASC_SG_LIST_PER_Q - 1;
8038 scsi_sg_q.sg_cur_list_cnt =
8039 ASC_SG_LIST_PER_Q - 1;
8040 }
8041 } else {
8042 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
8043 sg_list_dwords = sg_entry_cnt << 1;
8044 if (i == 0) {
8045 scsi_sg_q.sg_list_cnt = sg_entry_cnt;
8046 scsi_sg_q.sg_cur_list_cnt =
8047 sg_entry_cnt;
8048 } else {
8049 scsi_sg_q.sg_list_cnt =
8050 sg_entry_cnt - 1;
8051 scsi_sg_q.sg_cur_list_cnt =
8052 sg_entry_cnt - 1;
8053 }
8054 sg_entry_cnt = 0;
8055 }
8056 next_qp = AscReadLramByte(iop_base,
8057 (ushort)(q_addr +
8058 ASC_SCSIQ_B_FWD));
8059 scsi_sg_q.q_no = next_qp;
8060 q_addr = ASC_QNO_TO_QADDR(next_qp);
8061 AscMemWordCopyPtrToLram(iop_base,
8062 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
8063 (uchar *)&scsi_sg_q,
8064 sizeof(ASC_SG_LIST_Q) >> 1);
8065 AscMemDWordCopyPtrToLram(iop_base,
8066 q_addr + ASC_SGQ_LIST_BEG,
8067 (uchar *)&sg_head->
8068 sg_list[sg_index],
8069 sg_list_dwords);
8070 sg_index += ASC_SG_LIST_PER_Q;
8071 scsiq->next_sg_index = sg_index;
8072 }
8073 } else {
8074 scsiq->q1.cntl &= ~QC_SG_HEAD;
8075 }
8076 sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
8077 scsiq->q1.data_addr = saved_data_addr;
8078 scsiq->q1.data_cnt = saved_data_cnt;
8079 return (sta);
8080}
8081
8082static int
8083AscSendScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar n_q_required)
8084{
8085 PortAddr iop_base;
8086 uchar free_q_head;
8087 uchar next_qp;
8088 uchar tid_no;
8089 uchar target_ix;
8090 int sta;
8091
8092 iop_base = asc_dvc->iop_base;
8093 target_ix = scsiq->q2.target_ix;
8094 tid_no = ASC_TIX_TO_TID(target_ix);
8095 sta = 0;
8096 free_q_head = (uchar)AscGetVarFreeQHead(iop_base);
8097 if (n_q_required > 1) {
8098 next_qp = AscAllocMultipleFreeQueue(iop_base, free_q_head,
8099 (uchar)n_q_required);
8100 if (next_qp != ASC_QLINK_END) {
8101 asc_dvc->last_q_shortage = 0;
8102 scsiq->sg_head->queue_cnt = n_q_required - 1;
8103 scsiq->q1.q_no = free_q_head;
8104 sta = AscPutReadySgListQueue(asc_dvc, scsiq,
8105 free_q_head);
8106 }
8107 } else if (n_q_required == 1) {
8108 next_qp = AscAllocFreeQueue(iop_base, free_q_head);
8109 if (next_qp != ASC_QLINK_END) {
8110 scsiq->q1.q_no = free_q_head;
8111 sta = AscPutReadyQueue(asc_dvc, scsiq, free_q_head);
8112 }
8113 }
8114 if (sta == 1) {
8115 AscPutVarFreeQHead(iop_base, next_qp);
8116 asc_dvc->cur_total_qng += n_q_required;
8117 asc_dvc->cur_dvc_qng[tid_no]++;
8118 }
8119 return sta;
8120}
8121
8122#define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16
8123static uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = {
8124 INQUIRY,
8125 REQUEST_SENSE,
8126 READ_CAPACITY,
8127 READ_TOC,
8128 MODE_SELECT,
8129 MODE_SENSE,
8130 MODE_SELECT_10,
8131 MODE_SENSE_10,
8132 0xFF,
8133 0xFF,
8134 0xFF,
8135 0xFF,
8136 0xFF,
8137 0xFF,
8138 0xFF,
8139 0xFF
8140};
8141
8142static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq)
8143{
8144 PortAddr iop_base;
8145 int sta;
8146 int n_q_required;
8147 bool disable_syn_offset_one_fix;
8148 int i;
8149 u32 addr;
8150 ushort sg_entry_cnt = 0;
8151 ushort sg_entry_cnt_minus_one = 0;
8152 uchar target_ix;
8153 uchar tid_no;
8154 uchar sdtr_data;
8155 uchar extra_bytes;
8156 uchar scsi_cmd;
8157 uchar disable_cmd;
8158 ASC_SG_HEAD *sg_head;
8159 unsigned long data_cnt;
8160
8161 iop_base = asc_dvc->iop_base;
8162 sg_head = scsiq->sg_head;
8163 if (asc_dvc->err_code != 0)
8164 return ASC_ERROR;
8165 scsiq->q1.q_no = 0;
8166 if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
8167 scsiq->q1.extra_bytes = 0;
8168 }
8169 sta = 0;
8170 target_ix = scsiq->q2.target_ix;
8171 tid_no = ASC_TIX_TO_TID(target_ix);
8172 n_q_required = 1;
8173 if (scsiq->cdbptr[0] == REQUEST_SENSE) {
8174 if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
8175 asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
8176 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
8177 AscMsgOutSDTR(asc_dvc,
8178 asc_dvc->
8179 sdtr_period_tbl[(sdtr_data >> 4) &
8180 (uchar)(asc_dvc->
8181 max_sdtr_index -
8182 1)],
8183 (uchar)(sdtr_data & (uchar)
8184 ASC_SYN_MAX_OFFSET));
8185 scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
8186 }
8187 }
8188 if (asc_dvc->in_critical_cnt != 0) {
8189 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
8190 return ASC_ERROR;
8191 }
8192 asc_dvc->in_critical_cnt++;
8193 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
8194 if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
8195 asc_dvc->in_critical_cnt--;
8196 return ASC_ERROR;
8197 }
8198 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
8199 asc_dvc->in_critical_cnt--;
8200 return ASC_ERROR;
8201 }
8202 if (sg_entry_cnt == 1) {
8203 scsiq->q1.data_addr = cpu_to_le32(sg_head->sg_list[0].addr);
8204 scsiq->q1.data_cnt = cpu_to_le32(sg_head->sg_list[0].bytes);
8205 scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
8206 }
8207 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
8208 }
8209 scsi_cmd = scsiq->cdbptr[0];
8210 disable_syn_offset_one_fix = false;
8211 if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
8212 !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
8213 if (scsiq->q1.cntl & QC_SG_HEAD) {
8214 data_cnt = 0;
8215 for (i = 0; i < sg_entry_cnt; i++) {
8216 data_cnt += le32_to_cpu(sg_head->sg_list[i].
8217 bytes);
8218 }
8219 } else {
8220 data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
8221 }
8222 if (data_cnt != 0UL) {
8223 if (data_cnt < 512UL) {
8224 disable_syn_offset_one_fix = true;
8225 } else {
8226 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST;
8227 i++) {
8228 disable_cmd =
8229 _syn_offset_one_disable_cmd[i];
8230 if (disable_cmd == 0xFF) {
8231 break;
8232 }
8233 if (scsi_cmd == disable_cmd) {
8234 disable_syn_offset_one_fix =
8235 true;
8236 break;
8237 }
8238 }
8239 }
8240 }
8241 }
8242 if (disable_syn_offset_one_fix) {
8243 scsiq->q2.tag_code &= ~SIMPLE_QUEUE_TAG;
8244 scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
8245 ASC_TAG_FLAG_DISABLE_DISCONNECT);
8246 } else {
8247 scsiq->q2.tag_code &= 0x27;
8248 }
8249 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
8250 if (asc_dvc->bug_fix_cntl) {
8251 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
8252 if ((scsi_cmd == READ_6) ||
8253 (scsi_cmd == READ_10)) {
8254 addr = le32_to_cpu(sg_head->
8255 sg_list
8256 [sg_entry_cnt_minus_one].
8257 addr) +
8258 le32_to_cpu(sg_head->
8259 sg_list
8260 [sg_entry_cnt_minus_one].
8261 bytes);
8262 extra_bytes =
8263 (uchar)((ushort)addr & 0x0003);
8264 if ((extra_bytes != 0)
8265 &&
8266 ((scsiq->q2.
8267 tag_code &
8268 ASC_TAG_FLAG_EXTRA_BYTES)
8269 == 0)) {
8270 scsiq->q2.tag_code |=
8271 ASC_TAG_FLAG_EXTRA_BYTES;
8272 scsiq->q1.extra_bytes =
8273 extra_bytes;
8274 data_cnt =
8275 le32_to_cpu(sg_head->
8276 sg_list
8277 [sg_entry_cnt_minus_one].
8278 bytes);
8279 data_cnt -= extra_bytes;
8280 sg_head->
8281 sg_list
8282 [sg_entry_cnt_minus_one].
8283 bytes =
8284 cpu_to_le32(data_cnt);
8285 }
8286 }
8287 }
8288 }
8289 sg_head->entry_to_copy = sg_head->entry_cnt;
8290 n_q_required = AscSgListToQueue(sg_entry_cnt);
8291 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
8292 (uint) n_q_required)
8293 || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
8294 if ((sta =
8295 AscSendScsiQueue(asc_dvc, scsiq,
8296 n_q_required)) == 1) {
8297 asc_dvc->in_critical_cnt--;
8298 return (sta);
8299 }
8300 }
8301 } else {
8302 if (asc_dvc->bug_fix_cntl) {
8303 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
8304 if ((scsi_cmd == READ_6) ||
8305 (scsi_cmd == READ_10)) {
8306 addr =
8307 le32_to_cpu(scsiq->q1.data_addr) +
8308 le32_to_cpu(scsiq->q1.data_cnt);
8309 extra_bytes =
8310 (uchar)((ushort)addr & 0x0003);
8311 if ((extra_bytes != 0)
8312 &&
8313 ((scsiq->q2.
8314 tag_code &
8315 ASC_TAG_FLAG_EXTRA_BYTES)
8316 == 0)) {
8317 data_cnt =
8318 le32_to_cpu(scsiq->q1.
8319 data_cnt);
8320 if (((ushort)data_cnt & 0x01FF)
8321 == 0) {
8322 scsiq->q2.tag_code |=
8323 ASC_TAG_FLAG_EXTRA_BYTES;
8324 data_cnt -= extra_bytes;
8325 scsiq->q1.data_cnt =
8326 cpu_to_le32
8327 (data_cnt);
8328 scsiq->q1.extra_bytes =
8329 extra_bytes;
8330 }
8331 }
8332 }
8333 }
8334 }
8335 n_q_required = 1;
8336 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
8337 ((scsiq->q1.cntl & QC_URGENT) != 0)) {
8338 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
8339 n_q_required)) == 1) {
8340 asc_dvc->in_critical_cnt--;
8341 return (sta);
8342 }
8343 }
8344 }
8345 asc_dvc->in_critical_cnt--;
8346 return (sta);
8347}
8348
8349
8350
8351
8352
8353
8354
8355
8356
8357
8358
8359
8360
8361
8362
8363
8364
8365
8366
8367
8368
8369
8370static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, adv_req_t *reqp)
8371{
8372 AdvPortAddr iop_base;
8373 ADV_CARR_T *new_carrp;
8374 ADV_SCSI_REQ_Q *scsiq = &reqp->scsi_req_q;
8375
8376
8377
8378
8379 if (scsiq->target_id > ADV_MAX_TID) {
8380 scsiq->host_status = QHSTA_M_INVALID_DEVICE;
8381 scsiq->done_status = QD_WITH_ERROR;
8382 return ADV_ERROR;
8383 }
8384
8385 iop_base = asc_dvc->iop_base;
8386
8387
8388
8389
8390
8391 new_carrp = adv_get_next_carrier(asc_dvc);
8392 if (!new_carrp) {
8393 ASC_DBG(1, "No free carriers\n");
8394 return ADV_BUSY;
8395 }
8396
8397 asc_dvc->carr_pending_cnt++;
8398
8399
8400 scsiq->scsiq_ptr = cpu_to_le32(scsiq->srb_tag);
8401 scsiq->scsiq_rptr = cpu_to_le32(reqp->req_addr);
8402
8403 scsiq->carr_va = asc_dvc->icq_sp->carr_va;
8404 scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
8405
8406
8407
8408
8409
8410
8411 asc_dvc->icq_sp->areq_vpa = scsiq->scsiq_rptr;
8412
8413
8414
8415
8416
8417
8418 asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
8419
8420
8421
8422
8423 asc_dvc->icq_sp = new_carrp;
8424
8425 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
8426 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
8427
8428
8429
8430 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
8431 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
8432
8433
8434
8435
8436
8437 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
8438 ADV_TICKLE_NOP);
8439 }
8440 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
8441
8442
8443
8444
8445 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
8446 le32_to_cpu(new_carrp->carr_pa));
8447 }
8448
8449 return ADV_SUCCESS;
8450}
8451
8452
8453
8454
8455static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
8456{
8457 int ret, err_code;
8458 struct asc_board *boardp = shost_priv(scp->device->host);
8459
8460 ASC_DBG(1, "scp 0x%p\n", scp);
8461
8462 if (ASC_NARROW_BOARD(boardp)) {
8463 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
8464 struct asc_scsi_q asc_scsi_q;
8465
8466 ret = asc_build_req(boardp, scp, &asc_scsi_q);
8467 if (ret != ASC_NOERROR) {
8468 ASC_STATS(scp->device->host, build_error);
8469 return ret;
8470 }
8471
8472 ret = AscExeScsiQueue(asc_dvc, &asc_scsi_q);
8473 kfree(asc_scsi_q.sg_head);
8474 err_code = asc_dvc->err_code;
8475 } else {
8476 ADV_DVC_VAR *adv_dvc = &boardp->dvc_var.adv_dvc_var;
8477 adv_req_t *adv_reqp;
8478
8479 switch (adv_build_req(boardp, scp, &adv_reqp)) {
8480 case ASC_NOERROR:
8481 ASC_DBG(3, "adv_build_req ASC_NOERROR\n");
8482 break;
8483 case ASC_BUSY:
8484 ASC_DBG(1, "adv_build_req ASC_BUSY\n");
8485
8486
8487
8488
8489
8490
8491 return ASC_BUSY;
8492 case ASC_ERROR:
8493 default:
8494 ASC_DBG(1, "adv_build_req ASC_ERROR\n");
8495 ASC_STATS(scp->device->host, build_error);
8496 return ASC_ERROR;
8497 }
8498
8499 ret = AdvExeScsiQueue(adv_dvc, adv_reqp);
8500 err_code = adv_dvc->err_code;
8501 }
8502
8503 switch (ret) {
8504 case ASC_NOERROR:
8505 ASC_STATS(scp->device->host, exe_noerror);
8506
8507
8508
8509
8510 boardp->reqcnt[scp->device->id]++;
8511 ASC_DBG(1, "ExeScsiQueue() ASC_NOERROR\n");
8512 break;
8513 case ASC_BUSY:
8514 ASC_DBG(1, "ExeScsiQueue() ASC_BUSY\n");
8515 ASC_STATS(scp->device->host, exe_busy);
8516 break;
8517 case ASC_ERROR:
8518 scmd_printk(KERN_ERR, scp, "ExeScsiQueue() ASC_ERROR, "
8519 "err_code 0x%x\n", err_code);
8520 ASC_STATS(scp->device->host, exe_error);
8521 scp->result = HOST_BYTE(DID_ERROR);
8522 break;
8523 default:
8524 scmd_printk(KERN_ERR, scp, "ExeScsiQueue() unknown, "
8525 "err_code 0x%x\n", err_code);
8526 ASC_STATS(scp->device->host, exe_unknown);
8527 scp->result = HOST_BYTE(DID_ERROR);
8528 break;
8529 }
8530
8531 ASC_DBG(1, "end\n");
8532 return ret;
8533}
8534
8535
8536
8537
8538
8539
8540
8541static int
8542advansys_queuecommand_lck(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
8543{
8544 struct Scsi_Host *shost = scp->device->host;
8545 int asc_res, result = 0;
8546
8547 ASC_STATS(shost, queuecommand);
8548 scp->scsi_done = done;
8549
8550 asc_res = asc_execute_scsi_cmnd(scp);
8551
8552 switch (asc_res) {
8553 case ASC_NOERROR:
8554 break;
8555 case ASC_BUSY:
8556 result = SCSI_MLQUEUE_HOST_BUSY;
8557 break;
8558 case ASC_ERROR:
8559 default:
8560 asc_scsi_done(scp);
8561 break;
8562 }
8563
8564 return result;
8565}
8566
8567static DEF_SCSI_QCMD(advansys_queuecommand)
8568
8569static ushort AscGetEisaChipCfg(PortAddr iop_base)
8570{
8571 PortAddr eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
8572 (PortAddr) (ASC_EISA_CFG_IOP_MASK);
8573 return inpw(eisa_cfg_iop);
8574}
8575
8576
8577
8578
8579
8580static unsigned short AscGetChipBiosAddress(PortAddr iop_base,
8581 unsigned short bus_type)
8582{
8583 unsigned short cfg_lsw;
8584 unsigned short bios_addr;
8585
8586
8587
8588
8589
8590
8591 if (bus_type & ASC_IS_PCI)
8592 return 0;
8593
8594 if ((bus_type & ASC_IS_EISA) != 0) {
8595 cfg_lsw = AscGetEisaChipCfg(iop_base);
8596 cfg_lsw &= 0x000F;
8597 bios_addr = ASC_BIOS_MIN_ADDR + cfg_lsw * ASC_BIOS_BANK_SIZE;
8598 return bios_addr;
8599 }
8600
8601 cfg_lsw = AscGetChipCfgLsw(iop_base);
8602
8603
8604
8605
8606 if (bus_type == ASC_IS_ISAPNP)
8607 cfg_lsw &= 0x7FFF;
8608 bios_addr = ASC_BIOS_MIN_ADDR + (cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE;
8609 return bios_addr;
8610}
8611
8612static uchar AscSetChipScsiID(PortAddr iop_base, uchar new_host_id)
8613{
8614 ushort cfg_lsw;
8615
8616 if (AscGetChipScsiID(iop_base) == new_host_id) {
8617 return (new_host_id);
8618 }
8619 cfg_lsw = AscGetChipCfgLsw(iop_base);
8620 cfg_lsw &= 0xF8FF;
8621 cfg_lsw |= (ushort)((new_host_id & ASC_MAX_TID) << 8);
8622 AscSetChipCfgLsw(iop_base, cfg_lsw);
8623 return (AscGetChipScsiID(iop_base));
8624}
8625
8626static unsigned char AscGetChipScsiCtrl(PortAddr iop_base)
8627{
8628 unsigned char sc;
8629
8630 AscSetBank(iop_base, 1);
8631 sc = inp(iop_base + IOP_REG_SC);
8632 AscSetBank(iop_base, 0);
8633 return sc;
8634}
8635
8636static unsigned char AscGetChipVersion(PortAddr iop_base,
8637 unsigned short bus_type)
8638{
8639 if (bus_type & ASC_IS_EISA) {
8640 PortAddr eisa_iop;
8641 unsigned char revision;
8642 eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
8643 (PortAddr) ASC_EISA_REV_IOP_MASK;
8644 revision = inp(eisa_iop);
8645 return ASC_CHIP_MIN_VER_EISA - 1 + revision;
8646 }
8647 return AscGetChipVerNo(iop_base);
8648}
8649
8650#ifdef CONFIG_ISA
8651static void AscEnableIsaDma(uchar dma_channel)
8652{
8653 if (dma_channel < 4) {
8654 outp(0x000B, (ushort)(0xC0 | dma_channel));
8655 outp(0x000A, dma_channel);
8656 } else if (dma_channel < 8) {
8657 outp(0x00D6, (ushort)(0xC0 | (dma_channel - 4)));
8658 outp(0x00D4, (ushort)(dma_channel - 4));
8659 }
8660}
8661#endif
8662
8663static int AscStopQueueExe(PortAddr iop_base)
8664{
8665 int count = 0;
8666
8667 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
8668 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
8669 ASC_STOP_REQ_RISC_STOP);
8670 do {
8671 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
8672 ASC_STOP_ACK_RISC_STOP) {
8673 return (1);
8674 }
8675 mdelay(100);
8676 } while (count++ < 20);
8677 }
8678 return (0);
8679}
8680
8681static unsigned int AscGetMaxDmaCount(ushort bus_type)
8682{
8683 if (bus_type & ASC_IS_ISA)
8684 return ASC_MAX_ISA_DMA_COUNT;
8685 else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
8686 return ASC_MAX_VL_DMA_COUNT;
8687 return ASC_MAX_PCI_DMA_COUNT;
8688}
8689
8690#ifdef CONFIG_ISA
8691static ushort AscGetIsaDmaChannel(PortAddr iop_base)
8692{
8693 ushort channel;
8694
8695 channel = AscGetChipCfgLsw(iop_base) & 0x0003;
8696 if (channel == 0x03)
8697 return (0);
8698 else if (channel == 0x00)
8699 return (7);
8700 return (channel + 4);
8701}
8702
8703static ushort AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel)
8704{
8705 ushort cfg_lsw;
8706 uchar value;
8707
8708 if ((dma_channel >= 5) && (dma_channel <= 7)) {
8709 if (dma_channel == 7)
8710 value = 0x00;
8711 else
8712 value = dma_channel - 4;
8713 cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
8714 cfg_lsw |= value;
8715 AscSetChipCfgLsw(iop_base, cfg_lsw);
8716 return (AscGetIsaDmaChannel(iop_base));
8717 }
8718 return 0;
8719}
8720
8721static uchar AscGetIsaDmaSpeed(PortAddr iop_base)
8722{
8723 uchar speed_value;
8724
8725 AscSetBank(iop_base, 1);
8726 speed_value = AscReadChipDmaSpeed(iop_base);
8727 speed_value &= 0x07;
8728 AscSetBank(iop_base, 0);
8729 return speed_value;
8730}
8731
8732static uchar AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value)
8733{
8734 speed_value &= 0x07;
8735 AscSetBank(iop_base, 1);
8736 AscWriteChipDmaSpeed(iop_base, speed_value);
8737 AscSetBank(iop_base, 0);
8738 return AscGetIsaDmaSpeed(iop_base);
8739}
8740#endif
8741
8742static void AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc)
8743{
8744 int i;
8745 PortAddr iop_base;
8746 uchar chip_version;
8747
8748 iop_base = asc_dvc->iop_base;
8749 asc_dvc->err_code = 0;
8750 if ((asc_dvc->bus_type &
8751 (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
8752 asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
8753 }
8754 AscSetChipControl(iop_base, CC_HALT);
8755 AscSetChipStatus(iop_base, 0);
8756 asc_dvc->bug_fix_cntl = 0;
8757 asc_dvc->pci_fix_asyn_xfer = 0;
8758 asc_dvc->pci_fix_asyn_xfer_always = 0;
8759
8760 asc_dvc->sdtr_done = 0;
8761 asc_dvc->cur_total_qng = 0;
8762 asc_dvc->is_in_int = false;
8763 asc_dvc->in_critical_cnt = 0;
8764 asc_dvc->last_q_shortage = 0;
8765 asc_dvc->use_tagged_qng = 0;
8766 asc_dvc->no_scam = 0;
8767 asc_dvc->unit_not_ready = 0;
8768 asc_dvc->queue_full_or_busy = 0;
8769 asc_dvc->redo_scam = 0;
8770 asc_dvc->res2 = 0;
8771 asc_dvc->min_sdtr_index = 0;
8772 asc_dvc->cfg->can_tagged_qng = 0;
8773 asc_dvc->cfg->cmd_qng_enabled = 0;
8774 asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
8775 asc_dvc->init_sdtr = 0;
8776 asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
8777 asc_dvc->scsi_reset_wait = 3;
8778 asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
8779 asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
8780 asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
8781 asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
8782 asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
8783 chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
8784 asc_dvc->cfg->chip_version = chip_version;
8785 asc_dvc->sdtr_period_tbl = asc_syn_xfer_period;
8786 asc_dvc->max_sdtr_index = 7;
8787 if ((asc_dvc->bus_type & ASC_IS_PCI) &&
8788 (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
8789 asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
8790 asc_dvc->sdtr_period_tbl = asc_syn_ultra_xfer_period;
8791 asc_dvc->max_sdtr_index = 15;
8792 if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) {
8793 AscSetExtraControl(iop_base,
8794 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
8795 } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
8796 AscSetExtraControl(iop_base,
8797 (SEC_ACTIVE_NEGATE |
8798 SEC_ENABLE_FILTER));
8799 }
8800 }
8801 if (asc_dvc->bus_type == ASC_IS_PCI) {
8802 AscSetExtraControl(iop_base,
8803 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
8804 }
8805
8806 asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
8807#ifdef CONFIG_ISA
8808 if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
8809 if (chip_version >= ASC_CHIP_MIN_VER_ISA_PNP) {
8810 AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
8811 asc_dvc->bus_type = ASC_IS_ISAPNP;
8812 }
8813 asc_dvc->cfg->isa_dma_channel =
8814 (uchar)AscGetIsaDmaChannel(iop_base);
8815 }
8816#endif
8817 for (i = 0; i <= ASC_MAX_TID; i++) {
8818 asc_dvc->cur_dvc_qng[i] = 0;
8819 asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
8820 asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *)0L;
8821 asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *)0L;
8822 asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
8823 }
8824}
8825
8826static int AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg)
8827{
8828 int retry;
8829
8830 for (retry = 0; retry < ASC_EEP_MAX_RETRY; retry++) {
8831 unsigned char read_back;
8832 AscSetChipEEPCmd(iop_base, cmd_reg);
8833 mdelay(1);
8834 read_back = AscGetChipEEPCmd(iop_base);
8835 if (read_back == cmd_reg)
8836 return 1;
8837 }
8838 return 0;
8839}
8840
8841static void AscWaitEEPRead(void)
8842{
8843 mdelay(1);
8844}
8845
8846static ushort AscReadEEPWord(PortAddr iop_base, uchar addr)
8847{
8848 ushort read_wval;
8849 uchar cmd_reg;
8850
8851 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
8852 AscWaitEEPRead();
8853 cmd_reg = addr | ASC_EEP_CMD_READ;
8854 AscWriteEEPCmdReg(iop_base, cmd_reg);
8855 AscWaitEEPRead();
8856 read_wval = AscGetChipEEPData(iop_base);
8857 AscWaitEEPRead();
8858 return read_wval;
8859}
8860
8861static ushort AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf,
8862 ushort bus_type)
8863{
8864 ushort wval;
8865 ushort sum;
8866 ushort *wbuf;
8867 int cfg_beg;
8868 int cfg_end;
8869 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
8870 int s_addr;
8871
8872 wbuf = (ushort *)cfg_buf;
8873 sum = 0;
8874
8875 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
8876 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
8877 sum += *wbuf;
8878 }
8879 if (bus_type & ASC_IS_VL) {
8880 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
8881 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
8882 } else {
8883 cfg_beg = ASC_EEP_DVC_CFG_BEG;
8884 cfg_end = ASC_EEP_MAX_DVC_ADDR;
8885 }
8886 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
8887 wval = AscReadEEPWord(iop_base, (uchar)s_addr);
8888 if (s_addr <= uchar_end_in_config) {
8889
8890
8891
8892
8893 *wbuf = le16_to_cpu(wval);
8894 } else {
8895
8896 *wbuf = wval;
8897 }
8898 sum += wval;
8899 }
8900
8901
8902
8903
8904 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
8905 return sum;
8906}
8907
8908static int AscTestExternalLram(ASC_DVC_VAR *asc_dvc)
8909{
8910 PortAddr iop_base;
8911 ushort q_addr;
8912 ushort saved_word;
8913 int sta;
8914
8915 iop_base = asc_dvc->iop_base;
8916 sta = 0;
8917 q_addr = ASC_QNO_TO_QADDR(241);
8918 saved_word = AscReadLramWord(iop_base, q_addr);
8919 AscSetChipLramAddr(iop_base, q_addr);
8920 AscSetChipLramData(iop_base, 0x55AA);
8921 mdelay(10);
8922 AscSetChipLramAddr(iop_base, q_addr);
8923 if (AscGetChipLramData(iop_base) == 0x55AA) {
8924 sta = 1;
8925 AscWriteLramWord(iop_base, q_addr, saved_word);
8926 }
8927 return (sta);
8928}
8929
8930static void AscWaitEEPWrite(void)
8931{
8932 mdelay(20);
8933}
8934
8935static int AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg)
8936{
8937 ushort read_back;
8938 int retry;
8939
8940 retry = 0;
8941 while (true) {
8942 AscSetChipEEPData(iop_base, data_reg);
8943 mdelay(1);
8944 read_back = AscGetChipEEPData(iop_base);
8945 if (read_back == data_reg) {
8946 return (1);
8947 }
8948 if (retry++ > ASC_EEP_MAX_RETRY) {
8949 return (0);
8950 }
8951 }
8952}
8953
8954static ushort AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val)
8955{
8956 ushort read_wval;
8957
8958 read_wval = AscReadEEPWord(iop_base, addr);
8959 if (read_wval != word_val) {
8960 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
8961 AscWaitEEPRead();
8962 AscWriteEEPDataReg(iop_base, word_val);
8963 AscWaitEEPRead();
8964 AscWriteEEPCmdReg(iop_base,
8965 (uchar)((uchar)ASC_EEP_CMD_WRITE | addr));
8966 AscWaitEEPWrite();
8967 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
8968 AscWaitEEPRead();
8969 return (AscReadEEPWord(iop_base, addr));
8970 }
8971 return (read_wval);
8972}
8973
8974static int AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf,
8975 ushort bus_type)
8976{
8977 int n_error;
8978 ushort *wbuf;
8979 ushort word;
8980 ushort sum;
8981 int s_addr;
8982 int cfg_beg;
8983 int cfg_end;
8984 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
8985
8986 wbuf = (ushort *)cfg_buf;
8987 n_error = 0;
8988 sum = 0;
8989
8990 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
8991 sum += *wbuf;
8992 if (*wbuf != AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
8993 n_error++;
8994 }
8995 }
8996 if (bus_type & ASC_IS_VL) {
8997 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
8998 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
8999 } else {
9000 cfg_beg = ASC_EEP_DVC_CFG_BEG;
9001 cfg_end = ASC_EEP_MAX_DVC_ADDR;
9002 }
9003 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
9004 if (s_addr <= uchar_end_in_config) {
9005
9006
9007
9008
9009 word = cpu_to_le16(*wbuf);
9010 if (word !=
9011 AscWriteEEPWord(iop_base, (uchar)s_addr, word)) {
9012 n_error++;
9013 }
9014 } else {
9015
9016 if (*wbuf !=
9017 AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
9018 n_error++;
9019 }
9020 }
9021 sum += *wbuf;
9022 }
9023
9024 *wbuf = sum;
9025 if (sum != AscWriteEEPWord(iop_base, (uchar)s_addr, sum)) {
9026 n_error++;
9027 }
9028
9029
9030 wbuf = (ushort *)cfg_buf;
9031
9032
9033
9034 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
9035 if (*wbuf != AscReadEEPWord(iop_base, (uchar)s_addr)) {
9036 n_error++;
9037 }
9038 }
9039 if (bus_type & ASC_IS_VL) {
9040 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
9041 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
9042 } else {
9043 cfg_beg = ASC_EEP_DVC_CFG_BEG;
9044 cfg_end = ASC_EEP_MAX_DVC_ADDR;
9045 }
9046 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
9047 if (s_addr <= uchar_end_in_config) {
9048
9049
9050
9051
9052 word =
9053 le16_to_cpu(AscReadEEPWord
9054 (iop_base, (uchar)s_addr));
9055 } else {
9056
9057 word = AscReadEEPWord(iop_base, (uchar)s_addr);
9058 }
9059 if (*wbuf != word) {
9060 n_error++;
9061 }
9062 }
9063
9064 if (AscReadEEPWord(iop_base, (uchar)s_addr) != sum) {
9065 n_error++;
9066 }
9067 return n_error;
9068}
9069
9070static int AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf,
9071 ushort bus_type)
9072{
9073 int retry;
9074 int n_error;
9075
9076 retry = 0;
9077 while (true) {
9078 if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
9079 bus_type)) == 0) {
9080 break;
9081 }
9082 if (++retry > ASC_EEP_MAX_RETRY) {
9083 break;
9084 }
9085 }
9086 return n_error;
9087}
9088
9089static int AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
9090{
9091 ASCEEP_CONFIG eep_config_buf;
9092 ASCEEP_CONFIG *eep_config;
9093 PortAddr iop_base;
9094 ushort chksum;
9095 ushort warn_code;
9096 ushort cfg_msw, cfg_lsw;
9097 int i;
9098 int write_eep = 0;
9099
9100 iop_base = asc_dvc->iop_base;
9101 warn_code = 0;
9102 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
9103 AscStopQueueExe(iop_base);
9104 if ((AscStopChip(iop_base)) ||
9105 (AscGetChipScsiCtrl(iop_base) != 0)) {
9106 asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
9107 AscResetChipAndScsiBus(asc_dvc);
9108 mdelay(asc_dvc->scsi_reset_wait * 1000);
9109 }
9110 if (!AscIsChipHalted(iop_base)) {
9111 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
9112 return (warn_code);
9113 }
9114 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
9115 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
9116 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
9117 return (warn_code);
9118 }
9119 eep_config = (ASCEEP_CONFIG *)&eep_config_buf;
9120 cfg_msw = AscGetChipCfgMsw(iop_base);
9121 cfg_lsw = AscGetChipCfgLsw(iop_base);
9122 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
9123 cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
9124 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
9125 AscSetChipCfgMsw(iop_base, cfg_msw);
9126 }
9127 chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
9128 ASC_DBG(1, "chksum 0x%x\n", chksum);
9129 if (chksum == 0) {
9130 chksum = 0xaa55;
9131 }
9132 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
9133 warn_code |= ASC_WARN_AUTO_CONFIG;
9134 if (asc_dvc->cfg->chip_version == 3) {
9135 if (eep_config->cfg_lsw != cfg_lsw) {
9136 warn_code |= ASC_WARN_EEPROM_RECOVER;
9137 eep_config->cfg_lsw =
9138 AscGetChipCfgLsw(iop_base);
9139 }
9140 if (eep_config->cfg_msw != cfg_msw) {
9141 warn_code |= ASC_WARN_EEPROM_RECOVER;
9142 eep_config->cfg_msw =
9143 AscGetChipCfgMsw(iop_base);
9144 }
9145 }
9146 }
9147 eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
9148 eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
9149 ASC_DBG(1, "eep_config->chksum 0x%x\n", eep_config->chksum);
9150 if (chksum != eep_config->chksum) {
9151 if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
9152 ASC_CHIP_VER_PCI_ULTRA_3050) {
9153 ASC_DBG(1, "chksum error ignored; EEPROM-less board\n");
9154 eep_config->init_sdtr = 0xFF;
9155 eep_config->disc_enable = 0xFF;
9156 eep_config->start_motor = 0xFF;
9157 eep_config->use_cmd_qng = 0;
9158 eep_config->max_total_qng = 0xF0;
9159 eep_config->max_tag_qng = 0x20;
9160 eep_config->cntl = 0xBFFF;
9161 ASC_EEP_SET_CHIP_ID(eep_config, 7);
9162 eep_config->no_scam = 0;
9163 eep_config->adapter_info[0] = 0;
9164 eep_config->adapter_info[1] = 0;
9165 eep_config->adapter_info[2] = 0;
9166 eep_config->adapter_info[3] = 0;
9167 eep_config->adapter_info[4] = 0;
9168
9169 eep_config->adapter_info[5] = 0xBB;
9170 } else {
9171 ASC_PRINT
9172 ("AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
9173 write_eep = 1;
9174 warn_code |= ASC_WARN_EEPROM_CHKSUM;
9175 }
9176 }
9177 asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
9178 asc_dvc->cfg->disc_enable = eep_config->disc_enable;
9179 asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
9180 asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
9181 asc_dvc->start_motor = eep_config->start_motor;
9182 asc_dvc->dvc_cntl = eep_config->cntl;
9183 asc_dvc->no_scam = eep_config->no_scam;
9184 asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
9185 asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
9186 asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
9187 asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
9188 asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
9189 asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
9190 if (!AscTestExternalLram(asc_dvc)) {
9191 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) ==
9192 ASC_IS_PCI_ULTRA)) {
9193 eep_config->max_total_qng =
9194 ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
9195 eep_config->max_tag_qng =
9196 ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
9197 } else {
9198 eep_config->cfg_msw |= 0x0800;
9199 cfg_msw |= 0x0800;
9200 AscSetChipCfgMsw(iop_base, cfg_msw);
9201 eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
9202 eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
9203 }
9204 } else {
9205 }
9206 if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
9207 eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
9208 }
9209 if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
9210 eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
9211 }
9212 if (eep_config->max_tag_qng > eep_config->max_total_qng) {
9213 eep_config->max_tag_qng = eep_config->max_total_qng;
9214 }
9215 if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
9216 eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
9217 }
9218 asc_dvc->max_total_qng = eep_config->max_total_qng;
9219 if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
9220 eep_config->use_cmd_qng) {
9221 eep_config->disc_enable = eep_config->use_cmd_qng;
9222 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
9223 }
9224 ASC_EEP_SET_CHIP_ID(eep_config,
9225 ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
9226 asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
9227 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
9228 !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
9229 asc_dvc->min_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
9230 }
9231
9232 for (i = 0; i <= ASC_MAX_TID; i++) {
9233 asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
9234 asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
9235 asc_dvc->cfg->sdtr_period_offset[i] =
9236 (uchar)(ASC_DEF_SDTR_OFFSET |
9237 (asc_dvc->min_sdtr_index << 4));
9238 }
9239 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
9240 if (write_eep) {
9241 if ((i = AscSetEEPConfig(iop_base, eep_config,
9242 asc_dvc->bus_type)) != 0) {
9243 ASC_PRINT1
9244 ("AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n",
9245 i);
9246 } else {
9247 ASC_PRINT
9248 ("AscInitFromEEP: Successfully re-wrote EEPROM.\n");
9249 }
9250 }
9251 return (warn_code);
9252}
9253
9254static int AscInitGetConfig(struct Scsi_Host *shost)
9255{
9256 struct asc_board *board = shost_priv(shost);
9257 ASC_DVC_VAR *asc_dvc = &board->dvc_var.asc_dvc_var;
9258 unsigned short warn_code = 0;
9259
9260 asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
9261 if (asc_dvc->err_code != 0)
9262 return asc_dvc->err_code;
9263
9264 if (AscFindSignature(asc_dvc->iop_base)) {
9265 AscInitAscDvcVar(asc_dvc);
9266 warn_code = AscInitFromEEP(asc_dvc);
9267 asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
9268 if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT)
9269 asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
9270 } else {
9271 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
9272 }
9273
9274 switch (warn_code) {
9275 case 0:
9276 break;
9277 case ASC_WARN_IO_PORT_ROTATE:
9278 shost_printk(KERN_WARNING, shost, "I/O port address "
9279 "modified\n");
9280 break;
9281 case ASC_WARN_AUTO_CONFIG:
9282 shost_printk(KERN_WARNING, shost, "I/O port increment switch "
9283 "enabled\n");
9284 break;
9285 case ASC_WARN_EEPROM_CHKSUM:
9286 shost_printk(KERN_WARNING, shost, "EEPROM checksum error\n");
9287 break;
9288 case ASC_WARN_IRQ_MODIFIED:
9289 shost_printk(KERN_WARNING, shost, "IRQ modified\n");
9290 break;
9291 case ASC_WARN_CMD_QNG_CONFLICT:
9292 shost_printk(KERN_WARNING, shost, "tag queuing enabled w/o "
9293 "disconnects\n");
9294 break;
9295 default:
9296 shost_printk(KERN_WARNING, shost, "unknown warning: 0x%x\n",
9297 warn_code);
9298 break;
9299 }
9300
9301 if (asc_dvc->err_code != 0)
9302 shost_printk(KERN_ERR, shost, "error 0x%x at init_state "
9303 "0x%x\n", asc_dvc->err_code, asc_dvc->init_state);
9304
9305 return asc_dvc->err_code;
9306}
9307
9308static int AscInitSetConfig(struct pci_dev *pdev, struct Scsi_Host *shost)
9309{
9310 struct asc_board *board = shost_priv(shost);
9311 ASC_DVC_VAR *asc_dvc = &board->dvc_var.asc_dvc_var;
9312 PortAddr iop_base = asc_dvc->iop_base;
9313 unsigned short cfg_msw;
9314 unsigned short warn_code = 0;
9315
9316 asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
9317 if (asc_dvc->err_code != 0)
9318 return asc_dvc->err_code;
9319 if (!AscFindSignature(asc_dvc->iop_base)) {
9320 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
9321 return asc_dvc->err_code;
9322 }
9323
9324 cfg_msw = AscGetChipCfgMsw(iop_base);
9325 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
9326 cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
9327 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
9328 AscSetChipCfgMsw(iop_base, cfg_msw);
9329 }
9330 if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
9331 asc_dvc->cfg->cmd_qng_enabled) {
9332 asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
9333 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
9334 }
9335 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
9336 warn_code |= ASC_WARN_AUTO_CONFIG;
9337 }
9338#ifdef CONFIG_PCI
9339 if (asc_dvc->bus_type & ASC_IS_PCI) {
9340 cfg_msw &= 0xFFC0;
9341 AscSetChipCfgMsw(iop_base, cfg_msw);
9342 if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
9343 } else {
9344 if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
9345 (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
9346 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
9347 asc_dvc->bug_fix_cntl |=
9348 ASC_BUG_FIX_ASYN_USE_SYN;
9349 }
9350 }
9351 } else
9352#endif
9353 if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
9354 if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
9355 == ASC_CHIP_VER_ASYN_BUG) {
9356 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
9357 }
9358 }
9359 if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
9360 asc_dvc->cfg->chip_scsi_id) {
9361 asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
9362 }
9363#ifdef CONFIG_ISA
9364 if (asc_dvc->bus_type & ASC_IS_ISA) {
9365 AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
9366 AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
9367 }
9368#endif
9369
9370 asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
9371
9372 switch (warn_code) {
9373 case 0:
9374 break;
9375 case ASC_WARN_IO_PORT_ROTATE:
9376 shost_printk(KERN_WARNING, shost, "I/O port address "
9377 "modified\n");
9378 break;
9379 case ASC_WARN_AUTO_CONFIG:
9380 shost_printk(KERN_WARNING, shost, "I/O port increment switch "
9381 "enabled\n");
9382 break;
9383 case ASC_WARN_EEPROM_CHKSUM:
9384 shost_printk(KERN_WARNING, shost, "EEPROM checksum error\n");
9385 break;
9386 case ASC_WARN_IRQ_MODIFIED:
9387 shost_printk(KERN_WARNING, shost, "IRQ modified\n");
9388 break;
9389 case ASC_WARN_CMD_QNG_CONFLICT:
9390 shost_printk(KERN_WARNING, shost, "tag queuing w/o "
9391 "disconnects\n");
9392 break;
9393 default:
9394 shost_printk(KERN_WARNING, shost, "unknown warning: 0x%x\n",
9395 warn_code);
9396 break;
9397 }
9398
9399 if (asc_dvc->err_code != 0)
9400 shost_printk(KERN_ERR, shost, "error 0x%x at init_state "
9401 "0x%x\n", asc_dvc->err_code, asc_dvc->init_state);
9402
9403 return asc_dvc->err_code;
9404}
9405
9406
9407
9408
9409
9410
9411
9412
9413
9414
9415
9416
9417
9418
9419
9420
9421
9422#ifdef CONFIG_PCI
9423static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config = {
9424 ADV_EEPROM_BIOS_ENABLE,
9425 0x0000,
9426 0xFFFF,
9427 0xFFFF,
9428 0xFFFF,
9429 0xFFFF,
9430 0xFFFF,
9431 0xFFFF,
9432 0,
9433 7,
9434 0,
9435 3,
9436 0,
9437 0,
9438 0,
9439 0xFFE7,
9440 0xFFFF,
9441 0,
9442 ASC_DEF_MAX_HOST_QNG,
9443 ASC_DEF_MAX_DVC_QNG,
9444 0,
9445 0,
9446 0,
9447 0,
9448 0,
9449 0,
9450 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
9451 ,
9452 0,
9453 0,
9454 0,
9455 0,
9456 0,
9457 0,
9458 0
9459};
9460
9461static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar = {
9462 0,
9463 0,
9464 0,
9465 0,
9466 0,
9467 0,
9468 0,
9469 0,
9470 0,
9471 1,
9472 1,
9473 1,
9474 1,
9475 1,
9476 1,
9477 0,
9478 0,
9479 0,
9480 1,
9481 1,
9482 0,
9483 0,
9484 0,
9485 0,
9486 0,
9487 0,
9488 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
9489 ,
9490 0,
9491 0,
9492 0,
9493 0,
9494 0,
9495 0,
9496 0
9497};
9498
9499static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config = {
9500 ADV_EEPROM_BIOS_ENABLE,
9501 0x0000,
9502 0xFFFF,
9503 0xFFFF,
9504 0x4444,
9505 0xFFFF,
9506 0xFFFF,
9507 0xFFFF,
9508 0,
9509 7,
9510 0,
9511 3,
9512 0,
9513 0,
9514 0,
9515 0xFFE7,
9516 0x4444,
9517 0x4444,
9518 ASC_DEF_MAX_HOST_QNG,
9519 ASC_DEF_MAX_DVC_QNG,
9520 0,
9521 0x4444,
9522 0,
9523 0,
9524 0,
9525 0,
9526 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
9527 ,
9528 0,
9529 0,
9530 0,
9531 0,
9532 0,
9533 0,
9534 0,
9535 0,
9536 0,
9537 0,
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 PCI_VENDOR_ID_ASP,
9557 PCI_DEVICE_ID_38C0800_REV1,
9558 0,
9559 0,
9560 0,
9561 0
9562};
9563
9564static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar = {
9565 0,
9566 0,
9567 0,
9568 0,
9569 0,
9570 0,
9571 0,
9572 0,
9573 0,
9574 1,
9575 1,
9576 1,
9577 1,
9578 1,
9579 1,
9580 0,
9581 0,
9582 0,
9583 1,
9584 1,
9585 0,
9586 0,
9587 0,
9588 0,
9589 0,
9590 0,
9591 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
9592 ,
9593 0,
9594 0,
9595 0,
9596 0,
9597 0,
9598 0,
9599 0,
9600 0,
9601 0,
9602 0,
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};
9628
9629static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config = {
9630 ADV_EEPROM_BIOS_ENABLE,
9631 0x0000,
9632 0xFFFF,
9633 0xFFFF,
9634 0x5555,
9635 0xFFFF,
9636 0xFFFF,
9637 0xFFFF,
9638 0,
9639 7,
9640 0,
9641 3,
9642 0,
9643 0,
9644 0,
9645 0xFFE7,
9646 0x5555,
9647 0x5555,
9648 ASC_DEF_MAX_HOST_QNG,
9649 ASC_DEF_MAX_DVC_QNG,
9650 0,
9651 0x5555,
9652 0,
9653 0,
9654 0,
9655 0,
9656 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
9657 ,
9658 0,
9659 0,
9660 0,
9661 0,
9662 0,
9663 0,
9664 0,
9665 0,
9666 0,
9667 0,
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 PCI_VENDOR_ID_ASP,
9687 PCI_DEVICE_ID_38C1600_REV1,
9688 0,
9689 0,
9690 0,
9691 0
9692};
9693
9694static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar = {
9695 0,
9696 0,
9697 0,
9698 0,
9699 0,
9700 0,
9701 0,
9702 0,
9703 0,
9704 1,
9705 1,
9706 1,
9707 1,
9708 1,
9709 1,
9710 0,
9711 0,
9712 0,
9713 1,
9714 1,
9715 0,
9716 0,
9717 0,
9718 0,
9719 0,
9720 0,
9721 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
9722 ,
9723 0,
9724 0,
9725 0,
9726 0,
9727 0,
9728 0,
9729 0,
9730 0,
9731 0,
9732 0,
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};
9758
9759
9760
9761
9762static void AdvWaitEEPCmd(AdvPortAddr iop_base)
9763{
9764 int eep_delay_ms;
9765
9766 for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++) {
9767 if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) &
9768 ASC_EEP_CMD_DONE) {
9769 break;
9770 }
9771 mdelay(1);
9772 }
9773 if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) ==
9774 0)
9775 BUG();
9776}
9777
9778
9779
9780
9781static ushort AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
9782{
9783 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
9784 ASC_EEP_CMD_READ | eep_word_addr);
9785 AdvWaitEEPCmd(iop_base);
9786 return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
9787}
9788
9789
9790
9791
9792static void AdvSet3550EEPConfig(AdvPortAddr iop_base,
9793 ADVEEP_3550_CONFIG *cfg_buf)
9794{
9795 ushort *wbuf;
9796 ushort addr, chksum;
9797 ushort *charfields;
9798
9799 wbuf = (ushort *)cfg_buf;
9800 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
9801 chksum = 0;
9802
9803 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
9804 AdvWaitEEPCmd(iop_base);
9805
9806
9807
9808
9809 for (addr = ADV_EEP_DVC_CFG_BEGIN;
9810 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
9811 ushort word;
9812
9813 if (*charfields++) {
9814 word = cpu_to_le16(*wbuf);
9815 } else {
9816 word = *wbuf;
9817 }
9818 chksum += *wbuf;
9819 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
9820 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
9821 ASC_EEP_CMD_WRITE | addr);
9822 AdvWaitEEPCmd(iop_base);
9823 mdelay(ADV_EEP_DELAY_MS);
9824 }
9825
9826
9827
9828
9829 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
9830 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
9831 AdvWaitEEPCmd(iop_base);
9832 wbuf++;
9833 charfields++;
9834
9835
9836
9837
9838 for (addr = ADV_EEP_DVC_CTL_BEGIN;
9839 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
9840 ushort word;
9841
9842 if (*charfields++) {
9843 word = cpu_to_le16(*wbuf);
9844 } else {
9845 word = *wbuf;
9846 }
9847 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
9848 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
9849 ASC_EEP_CMD_WRITE | addr);
9850 AdvWaitEEPCmd(iop_base);
9851 }
9852 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
9853 AdvWaitEEPCmd(iop_base);
9854}
9855
9856
9857
9858
9859static void AdvSet38C0800EEPConfig(AdvPortAddr iop_base,
9860 ADVEEP_38C0800_CONFIG *cfg_buf)
9861{
9862 ushort *wbuf;
9863 ushort *charfields;
9864 ushort addr, chksum;
9865
9866 wbuf = (ushort *)cfg_buf;
9867 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
9868 chksum = 0;
9869
9870 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
9871 AdvWaitEEPCmd(iop_base);
9872
9873
9874
9875
9876 for (addr = ADV_EEP_DVC_CFG_BEGIN;
9877 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
9878 ushort word;
9879
9880 if (*charfields++) {
9881 word = cpu_to_le16(*wbuf);
9882 } else {
9883 word = *wbuf;
9884 }
9885 chksum += *wbuf;
9886 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
9887 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
9888 ASC_EEP_CMD_WRITE | addr);
9889 AdvWaitEEPCmd(iop_base);
9890 mdelay(ADV_EEP_DELAY_MS);
9891 }
9892
9893
9894
9895
9896 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
9897 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
9898 AdvWaitEEPCmd(iop_base);
9899 wbuf++;
9900 charfields++;
9901
9902
9903
9904
9905 for (addr = ADV_EEP_DVC_CTL_BEGIN;
9906 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
9907 ushort word;
9908
9909 if (*charfields++) {
9910 word = cpu_to_le16(*wbuf);
9911 } else {
9912 word = *wbuf;
9913 }
9914 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
9915 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
9916 ASC_EEP_CMD_WRITE | addr);
9917 AdvWaitEEPCmd(iop_base);
9918 }
9919 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
9920 AdvWaitEEPCmd(iop_base);
9921}
9922
9923
9924
9925
9926static void AdvSet38C1600EEPConfig(AdvPortAddr iop_base,
9927 ADVEEP_38C1600_CONFIG *cfg_buf)
9928{
9929 ushort *wbuf;
9930 ushort *charfields;
9931 ushort addr, chksum;
9932
9933 wbuf = (ushort *)cfg_buf;
9934 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
9935 chksum = 0;
9936
9937 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
9938 AdvWaitEEPCmd(iop_base);
9939
9940
9941
9942
9943 for (addr = ADV_EEP_DVC_CFG_BEGIN;
9944 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
9945 ushort word;
9946
9947 if (*charfields++) {
9948 word = cpu_to_le16(*wbuf);
9949 } else {
9950 word = *wbuf;
9951 }
9952 chksum += *wbuf;
9953 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
9954 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
9955 ASC_EEP_CMD_WRITE | addr);
9956 AdvWaitEEPCmd(iop_base);
9957 mdelay(ADV_EEP_DELAY_MS);
9958 }
9959
9960
9961
9962
9963 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
9964 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
9965 AdvWaitEEPCmd(iop_base);
9966 wbuf++;
9967 charfields++;
9968
9969
9970
9971
9972 for (addr = ADV_EEP_DVC_CTL_BEGIN;
9973 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
9974 ushort word;
9975
9976 if (*charfields++) {
9977 word = cpu_to_le16(*wbuf);
9978 } else {
9979 word = *wbuf;
9980 }
9981 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
9982 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
9983 ASC_EEP_CMD_WRITE | addr);
9984 AdvWaitEEPCmd(iop_base);
9985 }
9986 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
9987 AdvWaitEEPCmd(iop_base);
9988}
9989
9990
9991
9992
9993
9994
9995static ushort AdvGet3550EEPConfig(AdvPortAddr iop_base,
9996 ADVEEP_3550_CONFIG *cfg_buf)
9997{
9998 ushort wval, chksum;
9999 ushort *wbuf;
10000 int eep_addr;
10001 ushort *charfields;
10002
10003 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
10004 wbuf = (ushort *)cfg_buf;
10005 chksum = 0;
10006
10007 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
10008 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
10009 wval = AdvReadEEPWord(iop_base, eep_addr);
10010 chksum += wval;
10011 if (*charfields++) {
10012 *wbuf = le16_to_cpu(wval);
10013 } else {
10014 *wbuf = wval;
10015 }
10016 }
10017
10018 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
10019 wbuf++;
10020 charfields++;
10021
10022
10023 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
10024 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
10025 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
10026 if (*charfields++) {
10027 *wbuf = le16_to_cpu(*wbuf);
10028 }
10029 }
10030 return chksum;
10031}
10032
10033
10034
10035
10036
10037
10038static ushort AdvGet38C0800EEPConfig(AdvPortAddr iop_base,
10039 ADVEEP_38C0800_CONFIG *cfg_buf)
10040{
10041 ushort wval, chksum;
10042 ushort *wbuf;
10043 int eep_addr;
10044 ushort *charfields;
10045
10046 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
10047 wbuf = (ushort *)cfg_buf;
10048 chksum = 0;
10049
10050 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
10051 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
10052 wval = AdvReadEEPWord(iop_base, eep_addr);
10053 chksum += wval;
10054 if (*charfields++) {
10055 *wbuf = le16_to_cpu(wval);
10056 } else {
10057 *wbuf = wval;
10058 }
10059 }
10060
10061 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
10062 wbuf++;
10063 charfields++;
10064
10065
10066 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
10067 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
10068 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
10069 if (*charfields++) {
10070 *wbuf = le16_to_cpu(*wbuf);
10071 }
10072 }
10073 return chksum;
10074}
10075
10076
10077
10078
10079
10080
10081static ushort AdvGet38C1600EEPConfig(AdvPortAddr iop_base,
10082 ADVEEP_38C1600_CONFIG *cfg_buf)
10083{
10084 ushort wval, chksum;
10085 ushort *wbuf;
10086 int eep_addr;
10087 ushort *charfields;
10088
10089 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
10090 wbuf = (ushort *)cfg_buf;
10091 chksum = 0;
10092
10093 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
10094 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
10095 wval = AdvReadEEPWord(iop_base, eep_addr);
10096 chksum += wval;
10097 if (*charfields++) {
10098 *wbuf = le16_to_cpu(wval);
10099 } else {
10100 *wbuf = wval;
10101 }
10102 }
10103
10104 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
10105 wbuf++;
10106 charfields++;
10107
10108
10109 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
10110 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
10111 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
10112 if (*charfields++) {
10113 *wbuf = le16_to_cpu(*wbuf);
10114 }
10115 }
10116 return chksum;
10117}
10118
10119
10120
10121
10122
10123
10124
10125
10126
10127
10128
10129
10130
10131static int AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
10132{
10133 AdvPortAddr iop_base;
10134 ushort warn_code;
10135 ADVEEP_3550_CONFIG eep_config;
10136
10137 iop_base = asc_dvc->iop_base;
10138
10139 warn_code = 0;
10140
10141
10142
10143
10144
10145
10146 if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum) {
10147 warn_code |= ASC_WARN_EEPROM_CHKSUM;
10148
10149
10150
10151
10152 memcpy(&eep_config, &Default_3550_EEPROM_Config,
10153 sizeof(ADVEEP_3550_CONFIG));
10154
10155
10156
10157
10158
10159 eep_config.serial_number_word3 =
10160 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
10161
10162 eep_config.serial_number_word2 =
10163 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
10164
10165 eep_config.serial_number_word1 =
10166 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
10167
10168 AdvSet3550EEPConfig(iop_base, &eep_config);
10169 }
10170
10171
10172
10173
10174
10175
10176 asc_dvc->wdtr_able = eep_config.wdtr_able;
10177 asc_dvc->sdtr_able = eep_config.sdtr_able;
10178 asc_dvc->ultra_able = eep_config.ultra_able;
10179 asc_dvc->tagqng_able = eep_config.tagqng_able;
10180 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
10181 asc_dvc->max_host_qng = eep_config.max_host_qng;
10182 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
10183 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
10184 asc_dvc->start_motor = eep_config.start_motor;
10185 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
10186 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
10187 asc_dvc->no_scam = eep_config.scam_tolerant;
10188 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
10189 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
10190 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
10191
10192
10193
10194
10195
10196 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
10197 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
10198 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
10199
10200 if (eep_config.max_host_qng == 0) {
10201 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
10202 } else {
10203 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
10204 }
10205 }
10206
10207 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
10208 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
10209 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
10210
10211 if (eep_config.max_dvc_qng == 0) {
10212 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
10213 } else {
10214 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
10215 }
10216 }
10217
10218
10219
10220
10221
10222 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
10223 eep_config.max_dvc_qng = eep_config.max_host_qng;
10224 }
10225
10226
10227
10228
10229
10230 asc_dvc->max_host_qng = eep_config.max_host_qng;
10231 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
10232
10233
10234
10235
10236
10237
10238
10239
10240
10241 if (eep_config.termination == 0) {
10242 asc_dvc->cfg->termination = 0;
10243 } else {
10244
10245 if (eep_config.termination == 1) {
10246 asc_dvc->cfg->termination = TERM_CTL_SEL;
10247
10248
10249 } else if (eep_config.termination == 2) {
10250 asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
10251
10252
10253 } else if (eep_config.termination == 3) {
10254 asc_dvc->cfg->termination =
10255 TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
10256 } else {
10257
10258
10259
10260
10261 asc_dvc->cfg->termination = 0;
10262 warn_code |= ASC_WARN_EEPROM_TERMINATION;
10263 }
10264 }
10265
10266 return warn_code;
10267}
10268
10269
10270
10271
10272
10273
10274
10275
10276
10277
10278
10279
10280
10281static int AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
10282{
10283 AdvPortAddr iop_base;
10284 ushort warn_code;
10285 ADVEEP_38C0800_CONFIG eep_config;
10286 uchar tid, termination;
10287 ushort sdtr_speed = 0;
10288
10289 iop_base = asc_dvc->iop_base;
10290
10291 warn_code = 0;
10292
10293
10294
10295
10296
10297
10298 if (AdvGet38C0800EEPConfig(iop_base, &eep_config) !=
10299 eep_config.check_sum) {
10300 warn_code |= ASC_WARN_EEPROM_CHKSUM;
10301
10302
10303
10304
10305 memcpy(&eep_config, &Default_38C0800_EEPROM_Config,
10306 sizeof(ADVEEP_38C0800_CONFIG));
10307
10308
10309
10310
10311
10312 eep_config.serial_number_word3 =
10313 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
10314
10315 eep_config.serial_number_word2 =
10316 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
10317
10318 eep_config.serial_number_word1 =
10319 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
10320
10321 AdvSet38C0800EEPConfig(iop_base, &eep_config);
10322 }
10323
10324
10325
10326
10327
10328
10329 asc_dvc->wdtr_able = eep_config.wdtr_able;
10330 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
10331 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
10332 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
10333 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
10334 asc_dvc->tagqng_able = eep_config.tagqng_able;
10335 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
10336 asc_dvc->max_host_qng = eep_config.max_host_qng;
10337 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
10338 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
10339 asc_dvc->start_motor = eep_config.start_motor;
10340 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
10341 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
10342 asc_dvc->no_scam = eep_config.scam_tolerant;
10343 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
10344 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
10345 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
10346
10347
10348
10349
10350
10351 asc_dvc->sdtr_able = 0;
10352 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
10353 if (tid == 0) {
10354 sdtr_speed = asc_dvc->sdtr_speed1;
10355 } else if (tid == 4) {
10356 sdtr_speed = asc_dvc->sdtr_speed2;
10357 } else if (tid == 8) {
10358 sdtr_speed = asc_dvc->sdtr_speed3;
10359 } else if (tid == 12) {
10360 sdtr_speed = asc_dvc->sdtr_speed4;
10361 }
10362 if (sdtr_speed & ADV_MAX_TID) {
10363 asc_dvc->sdtr_able |= (1 << tid);
10364 }
10365 sdtr_speed >>= 4;
10366 }
10367
10368
10369
10370
10371
10372 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
10373 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
10374 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
10375
10376 if (eep_config.max_host_qng == 0) {
10377 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
10378 } else {
10379 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
10380 }
10381 }
10382
10383 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
10384 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
10385 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
10386
10387 if (eep_config.max_dvc_qng == 0) {
10388 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
10389 } else {
10390 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
10391 }
10392 }
10393
10394
10395
10396
10397
10398 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
10399 eep_config.max_dvc_qng = eep_config.max_host_qng;
10400 }
10401
10402
10403
10404
10405
10406 asc_dvc->max_host_qng = eep_config.max_host_qng;
10407 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
10408
10409
10410
10411
10412
10413
10414
10415
10416
10417 if (eep_config.termination_se == 0) {
10418 termination = 0;
10419 } else {
10420
10421 if (eep_config.termination_se == 1) {
10422 termination = 0;
10423
10424
10425 } else if (eep_config.termination_se == 2) {
10426 termination = TERM_SE_HI;
10427
10428
10429 } else if (eep_config.termination_se == 3) {
10430 termination = TERM_SE;
10431 } else {
10432
10433
10434
10435
10436 termination = 0;
10437 warn_code |= ASC_WARN_EEPROM_TERMINATION;
10438 }
10439 }
10440
10441 if (eep_config.termination_lvd == 0) {
10442 asc_dvc->cfg->termination = termination;
10443 } else {
10444
10445 if (eep_config.termination_lvd == 1) {
10446 asc_dvc->cfg->termination = termination;
10447
10448
10449 } else if (eep_config.termination_lvd == 2) {
10450 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
10451
10452
10453 } else if (eep_config.termination_lvd == 3) {
10454 asc_dvc->cfg->termination = termination | TERM_LVD;
10455 } else {
10456
10457
10458
10459
10460 asc_dvc->cfg->termination = termination;
10461 warn_code |= ASC_WARN_EEPROM_TERMINATION;
10462 }
10463 }
10464
10465 return warn_code;
10466}
10467
10468
10469
10470
10471
10472
10473
10474
10475
10476
10477
10478
10479
10480static int AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
10481{
10482 AdvPortAddr iop_base;
10483 ushort warn_code;
10484 ADVEEP_38C1600_CONFIG eep_config;
10485 uchar tid, termination;
10486 ushort sdtr_speed = 0;
10487
10488 iop_base = asc_dvc->iop_base;
10489
10490 warn_code = 0;
10491
10492
10493
10494
10495
10496
10497 if (AdvGet38C1600EEPConfig(iop_base, &eep_config) !=
10498 eep_config.check_sum) {
10499 struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc);
10500 warn_code |= ASC_WARN_EEPROM_CHKSUM;
10501
10502
10503
10504
10505 memcpy(&eep_config, &Default_38C1600_EEPROM_Config,
10506 sizeof(ADVEEP_38C1600_CONFIG));
10507
10508 if (PCI_FUNC(pdev->devfn) != 0) {
10509 u8 ints;
10510
10511
10512
10513
10514
10515 eep_config.cfg_lsw &= ~ADV_EEPROM_BIOS_ENABLE;
10516
10517
10518
10519
10520
10521
10522
10523
10524
10525
10526
10527
10528
10529 AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL, 0);
10530 ints = AdvReadByteRegister(iop_base, IOPB_GPIO_DATA);
10531 if ((ints & 0x01) == 0)
10532 eep_config.cfg_lsw &= ~ADV_EEPROM_INTAB;
10533 }
10534
10535
10536
10537
10538
10539 eep_config.serial_number_word3 =
10540 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
10541 eep_config.serial_number_word2 =
10542 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
10543 eep_config.serial_number_word1 =
10544 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
10545
10546 AdvSet38C1600EEPConfig(iop_base, &eep_config);
10547 }
10548
10549
10550
10551
10552
10553
10554
10555 asc_dvc->wdtr_able = eep_config.wdtr_able;
10556 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
10557 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
10558 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
10559 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
10560 asc_dvc->ppr_able = 0;
10561 asc_dvc->tagqng_able = eep_config.tagqng_able;
10562 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
10563 asc_dvc->max_host_qng = eep_config.max_host_qng;
10564 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
10565 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
10566 asc_dvc->start_motor = eep_config.start_motor;
10567 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
10568 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
10569 asc_dvc->no_scam = eep_config.scam_tolerant;
10570
10571
10572
10573
10574
10575 asc_dvc->sdtr_able = 0;
10576 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
10577 if (tid == 0) {
10578 sdtr_speed = asc_dvc->sdtr_speed1;
10579 } else if (tid == 4) {
10580 sdtr_speed = asc_dvc->sdtr_speed2;
10581 } else if (tid == 8) {
10582 sdtr_speed = asc_dvc->sdtr_speed3;
10583 } else if (tid == 12) {
10584 sdtr_speed = asc_dvc->sdtr_speed4;
10585 }
10586 if (sdtr_speed & ASC_MAX_TID) {
10587 asc_dvc->sdtr_able |= (1 << tid);
10588 }
10589 sdtr_speed >>= 4;
10590 }
10591
10592
10593
10594
10595
10596 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
10597 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
10598 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
10599
10600 if (eep_config.max_host_qng == 0) {
10601 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
10602 } else {
10603 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
10604 }
10605 }
10606
10607 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
10608 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
10609 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
10610
10611 if (eep_config.max_dvc_qng == 0) {
10612 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
10613 } else {
10614 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
10615 }
10616 }
10617
10618
10619
10620
10621
10622 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
10623 eep_config.max_dvc_qng = eep_config.max_host_qng;
10624 }
10625
10626
10627
10628
10629
10630 asc_dvc->max_host_qng = eep_config.max_host_qng;
10631 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
10632
10633
10634
10635
10636
10637
10638
10639
10640
10641 if (eep_config.termination_se == 0) {
10642 termination = 0;
10643 } else {
10644
10645 if (eep_config.termination_se == 1) {
10646 termination = 0;
10647
10648
10649 } else if (eep_config.termination_se == 2) {
10650 termination = TERM_SE_HI;
10651
10652
10653 } else if (eep_config.termination_se == 3) {
10654 termination = TERM_SE;
10655 } else {
10656
10657
10658
10659
10660 termination = 0;
10661 warn_code |= ASC_WARN_EEPROM_TERMINATION;
10662 }
10663 }
10664
10665 if (eep_config.termination_lvd == 0) {
10666 asc_dvc->cfg->termination = termination;
10667 } else {
10668
10669 if (eep_config.termination_lvd == 1) {
10670 asc_dvc->cfg->termination = termination;
10671
10672
10673 } else if (eep_config.termination_lvd == 2) {
10674 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
10675
10676
10677 } else if (eep_config.termination_lvd == 3) {
10678 asc_dvc->cfg->termination = termination | TERM_LVD;
10679 } else {
10680
10681
10682
10683
10684 asc_dvc->cfg->termination = termination;
10685 warn_code |= ASC_WARN_EEPROM_TERMINATION;
10686 }
10687 }
10688
10689 return warn_code;
10690}
10691
10692
10693
10694
10695
10696
10697
10698
10699
10700static int AdvInitGetConfig(struct pci_dev *pdev, struct Scsi_Host *shost)
10701{
10702 struct asc_board *board = shost_priv(shost);
10703 ADV_DVC_VAR *asc_dvc = &board->dvc_var.adv_dvc_var;
10704 unsigned short warn_code = 0;
10705 AdvPortAddr iop_base = asc_dvc->iop_base;
10706 u16 cmd;
10707 int status;
10708
10709 asc_dvc->err_code = 0;
10710
10711
10712
10713
10714
10715
10716
10717 asc_dvc->cfg->control_flag = 0;
10718 pci_read_config_word(pdev, PCI_COMMAND, &cmd);
10719 if ((cmd & PCI_COMMAND_PARITY) == 0)
10720 asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
10721
10722 asc_dvc->cfg->chip_version =
10723 AdvGetChipVersion(iop_base, asc_dvc->bus_type);
10724
10725 ASC_DBG(1, "iopb_chip_id_1: 0x%x 0x%x\n",
10726 (ushort)AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
10727 (ushort)ADV_CHIP_ID_BYTE);
10728
10729 ASC_DBG(1, "iopw_chip_id_0: 0x%x 0x%x\n",
10730 (ushort)AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
10731 (ushort)ADV_CHIP_ID_WORD);
10732
10733
10734
10735
10736 if (AdvFindSignature(iop_base) == 0) {
10737 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10738 return ADV_ERROR;
10739 } else {
10740
10741
10742
10743 if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
10744 asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
10745 asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
10746 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
10747 return ADV_ERROR;
10748 }
10749
10750
10751
10752
10753 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
10754 ADV_CTRL_REG_CMD_RESET);
10755 mdelay(100);
10756 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
10757 ADV_CTRL_REG_CMD_WR_IO_REG);
10758
10759 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
10760 status = AdvInitFrom38C1600EEP(asc_dvc);
10761 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
10762 status = AdvInitFrom38C0800EEP(asc_dvc);
10763 } else {
10764 status = AdvInitFrom3550EEP(asc_dvc);
10765 }
10766 warn_code |= status;
10767 }
10768
10769 if (warn_code != 0)
10770 shost_printk(KERN_WARNING, shost, "warning: 0x%x\n", warn_code);
10771
10772 if (asc_dvc->err_code)
10773 shost_printk(KERN_ERR, shost, "error code 0x%x\n",
10774 asc_dvc->err_code);
10775
10776 return asc_dvc->err_code;
10777}
10778#endif
10779
10780static struct scsi_host_template advansys_template = {
10781 .proc_name = DRV_NAME,
10782#ifdef CONFIG_PROC_FS
10783 .show_info = advansys_show_info,
10784#endif
10785 .name = DRV_NAME,
10786 .info = advansys_info,
10787 .queuecommand = advansys_queuecommand,
10788 .eh_host_reset_handler = advansys_reset,
10789 .bios_param = advansys_biosparam,
10790 .slave_configure = advansys_slave_configure,
10791
10792
10793
10794
10795
10796 .unchecked_isa_dma = true,
10797};
10798
10799static int advansys_wide_init_chip(struct Scsi_Host *shost)
10800{
10801 struct asc_board *board = shost_priv(shost);
10802 struct adv_dvc_var *adv_dvc = &board->dvc_var.adv_dvc_var;
10803 size_t sgblk_pool_size;
10804 int warn_code, err_code;
10805
10806
10807
10808
10809
10810 adv_dvc->carrier = dma_alloc_coherent(board->dev,
10811 ADV_CARRIER_BUFSIZE, &adv_dvc->carrier_addr, GFP_KERNEL);
10812 ASC_DBG(1, "carrier 0x%p\n", adv_dvc->carrier);
10813
10814 if (!adv_dvc->carrier)
10815 goto kmalloc_failed;
10816
10817
10818
10819
10820
10821
10822 board->adv_reqp_size = adv_dvc->max_host_qng * sizeof(adv_req_t);
10823 if (board->adv_reqp_size & 0x1f) {
10824 ASC_DBG(1, "unaligned reqp %lu bytes\n", sizeof(adv_req_t));
10825 board->adv_reqp_size = ADV_32BALIGN(board->adv_reqp_size);
10826 }
10827 board->adv_reqp = dma_alloc_coherent(board->dev, board->adv_reqp_size,
10828 &board->adv_reqp_addr, GFP_KERNEL);
10829
10830 if (!board->adv_reqp)
10831 goto kmalloc_failed;
10832
10833 ASC_DBG(1, "reqp 0x%p, req_cnt %d, bytes %lu\n", board->adv_reqp,
10834 adv_dvc->max_host_qng, board->adv_reqp_size);
10835
10836
10837
10838
10839
10840 sgblk_pool_size = sizeof(adv_sgblk_t) * ADV_TOT_SG_BLOCK;
10841 board->adv_sgblk_pool = dma_pool_create("adv_sgblk", board->dev,
10842 sgblk_pool_size, 32, 0);
10843
10844 ASC_DBG(1, "sg_cnt %d * %lu = %lu bytes\n", ADV_TOT_SG_BLOCK,
10845 sizeof(adv_sgblk_t), sgblk_pool_size);
10846
10847 if (!board->adv_sgblk_pool)
10848 goto kmalloc_failed;
10849
10850 if (adv_dvc->chip_type == ADV_CHIP_ASC3550) {
10851 ASC_DBG(2, "AdvInitAsc3550Driver()\n");
10852 warn_code = AdvInitAsc3550Driver(adv_dvc);
10853 } else if (adv_dvc->chip_type == ADV_CHIP_ASC38C0800) {
10854 ASC_DBG(2, "AdvInitAsc38C0800Driver()\n");
10855 warn_code = AdvInitAsc38C0800Driver(adv_dvc);
10856 } else {
10857 ASC_DBG(2, "AdvInitAsc38C1600Driver()\n");
10858 warn_code = AdvInitAsc38C1600Driver(adv_dvc);
10859 }
10860 err_code = adv_dvc->err_code;
10861
10862 if (warn_code || err_code) {
10863 shost_printk(KERN_WARNING, shost, "error: warn 0x%x, error "
10864 "0x%x\n", warn_code, err_code);
10865 }
10866
10867 goto exit;
10868
10869 kmalloc_failed:
10870 shost_printk(KERN_ERR, shost, "error: kmalloc() failed\n");
10871 err_code = ADV_ERROR;
10872 exit:
10873 return err_code;
10874}
10875
10876static void advansys_wide_free_mem(struct asc_board *board)
10877{
10878 struct adv_dvc_var *adv_dvc = &board->dvc_var.adv_dvc_var;
10879
10880 if (adv_dvc->carrier) {
10881 dma_free_coherent(board->dev, ADV_CARRIER_BUFSIZE,
10882 adv_dvc->carrier, adv_dvc->carrier_addr);
10883 adv_dvc->carrier = NULL;
10884 }
10885 if (board->adv_reqp) {
10886 dma_free_coherent(board->dev, board->adv_reqp_size,
10887 board->adv_reqp, board->adv_reqp_addr);
10888 board->adv_reqp = NULL;
10889 }
10890 if (board->adv_sgblk_pool) {
10891 dma_pool_destroy(board->adv_sgblk_pool);
10892 board->adv_sgblk_pool = NULL;
10893 }
10894}
10895
10896static int advansys_board_found(struct Scsi_Host *shost, unsigned int iop,
10897 int bus_type)
10898{
10899 struct pci_dev *pdev;
10900 struct asc_board *boardp = shost_priv(shost);
10901 ASC_DVC_VAR *asc_dvc_varp = NULL;
10902 ADV_DVC_VAR *adv_dvc_varp = NULL;
10903 int share_irq, warn_code, ret;
10904
10905 pdev = (bus_type == ASC_IS_PCI) ? to_pci_dev(boardp->dev) : NULL;
10906
10907 if (ASC_NARROW_BOARD(boardp)) {
10908 ASC_DBG(1, "narrow board\n");
10909 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
10910 asc_dvc_varp->bus_type = bus_type;
10911 asc_dvc_varp->drv_ptr = boardp;
10912 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
10913 asc_dvc_varp->iop_base = iop;
10914 } else {
10915#ifdef CONFIG_PCI
10916 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
10917 adv_dvc_varp->drv_ptr = boardp;
10918 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
10919 if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) {
10920 ASC_DBG(1, "wide board ASC-3550\n");
10921 adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
10922 } else if (pdev->device == PCI_DEVICE_ID_38C0800_REV1) {
10923 ASC_DBG(1, "wide board ASC-38C0800\n");
10924 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
10925 } else {
10926 ASC_DBG(1, "wide board ASC-38C1600\n");
10927 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
10928 }
10929
10930 boardp->asc_n_io_port = pci_resource_len(pdev, 1);
10931 boardp->ioremap_addr = pci_ioremap_bar(pdev, 1);
10932 if (!boardp->ioremap_addr) {
10933 shost_printk(KERN_ERR, shost, "ioremap(%lx, %d) "
10934 "returned NULL\n",
10935 (long)pci_resource_start(pdev, 1),
10936 boardp->asc_n_io_port);
10937 ret = -ENODEV;
10938 goto err_shost;
10939 }
10940 adv_dvc_varp->iop_base = (AdvPortAddr)boardp->ioremap_addr;
10941 ASC_DBG(1, "iop_base: 0x%p\n", adv_dvc_varp->iop_base);
10942
10943
10944
10945
10946
10947
10948 boardp->ioport = iop;
10949
10950 ASC_DBG(1, "iopb_chip_id_1 0x%x, iopw_chip_id_0 0x%x\n",
10951 (ushort)inp(iop + 1), (ushort)inpw(iop));
10952#endif
10953 }
10954
10955 if (ASC_NARROW_BOARD(boardp)) {
10956
10957
10958
10959
10960 switch (asc_dvc_varp->bus_type) {
10961#ifdef CONFIG_ISA
10962 case ASC_IS_ISA:
10963 shost->unchecked_isa_dma = true;
10964 share_irq = 0;
10965 break;
10966 case ASC_IS_VL:
10967 shost->unchecked_isa_dma = false;
10968 share_irq = 0;
10969 break;
10970 case ASC_IS_EISA:
10971 shost->unchecked_isa_dma = false;
10972 share_irq = IRQF_SHARED;
10973 break;
10974#endif
10975#ifdef CONFIG_PCI
10976 case ASC_IS_PCI:
10977 shost->unchecked_isa_dma = false;
10978 share_irq = IRQF_SHARED;
10979 break;
10980#endif
10981 default:
10982 shost_printk(KERN_ERR, shost, "unknown adapter type: "
10983 "%d\n", asc_dvc_varp->bus_type);
10984 shost->unchecked_isa_dma = false;
10985 share_irq = 0;
10986 break;
10987 }
10988
10989
10990
10991
10992
10993
10994
10995 ASC_DBG(2, "AscInitGetConfig()\n");
10996 ret = AscInitGetConfig(shost) ? -ENODEV : 0;
10997 } else {
10998#ifdef CONFIG_PCI
10999
11000
11001
11002
11003 shost->unchecked_isa_dma = false;
11004 share_irq = IRQF_SHARED;
11005 ASC_DBG(2, "AdvInitGetConfig()\n");
11006
11007 ret = AdvInitGetConfig(pdev, shost) ? -ENODEV : 0;
11008#else
11009 share_irq = 0;
11010 ret = -ENODEV;
11011#endif
11012 }
11013
11014 if (ret)
11015 goto err_unmap;
11016
11017
11018
11019
11020
11021 if (ASC_NARROW_BOARD(boardp)) {
11022
11023 ASCEEP_CONFIG *ep;
11024
11025
11026
11027
11028 boardp->init_tidmask |=
11029 ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
11030
11031
11032
11033
11034 ep = &boardp->eep_config.asc_eep;
11035
11036 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
11037 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
11038 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
11039 ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
11040 ep->start_motor = asc_dvc_varp->start_motor;
11041 ep->cntl = asc_dvc_varp->dvc_cntl;
11042 ep->no_scam = asc_dvc_varp->no_scam;
11043 ep->max_total_qng = asc_dvc_varp->max_total_qng;
11044 ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
11045
11046 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
11047 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
11048 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
11049 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
11050 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
11051 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
11052 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
11053
11054
11055
11056
11057 ASC_DBG(2, "AscInitSetConfig()\n");
11058 ret = AscInitSetConfig(pdev, shost) ? -ENODEV : 0;
11059 if (ret)
11060 goto err_unmap;
11061 } else {
11062 ADVEEP_3550_CONFIG *ep_3550;
11063 ADVEEP_38C0800_CONFIG *ep_38C0800;
11064 ADVEEP_38C1600_CONFIG *ep_38C1600;
11065
11066
11067
11068
11069 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
11070 ep_3550 = &boardp->eep_config.adv_3550_eep;
11071
11072 ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
11073 ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
11074 ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
11075 ep_3550->termination = adv_dvc_varp->cfg->termination;
11076 ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
11077 ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
11078 ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
11079 ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
11080 ep_3550->ultra_able = adv_dvc_varp->ultra_able;
11081 ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
11082 ep_3550->start_motor = adv_dvc_varp->start_motor;
11083 ep_3550->scsi_reset_delay =
11084 adv_dvc_varp->scsi_reset_wait;
11085 ep_3550->serial_number_word1 =
11086 adv_dvc_varp->cfg->serial1;
11087 ep_3550->serial_number_word2 =
11088 adv_dvc_varp->cfg->serial2;
11089 ep_3550->serial_number_word3 =
11090 adv_dvc_varp->cfg->serial3;
11091 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
11092 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
11093
11094 ep_38C0800->adapter_scsi_id =
11095 adv_dvc_varp->chip_scsi_id;
11096 ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
11097 ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
11098 ep_38C0800->termination_lvd =
11099 adv_dvc_varp->cfg->termination;
11100 ep_38C0800->disc_enable =
11101 adv_dvc_varp->cfg->disc_enable;
11102 ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
11103 ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
11104 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
11105 ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
11106 ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
11107 ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
11108 ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
11109 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
11110 ep_38C0800->start_motor = adv_dvc_varp->start_motor;
11111 ep_38C0800->scsi_reset_delay =
11112 adv_dvc_varp->scsi_reset_wait;
11113 ep_38C0800->serial_number_word1 =
11114 adv_dvc_varp->cfg->serial1;
11115 ep_38C0800->serial_number_word2 =
11116 adv_dvc_varp->cfg->serial2;
11117 ep_38C0800->serial_number_word3 =
11118 adv_dvc_varp->cfg->serial3;
11119 } else {
11120 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
11121
11122 ep_38C1600->adapter_scsi_id =
11123 adv_dvc_varp->chip_scsi_id;
11124 ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
11125 ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
11126 ep_38C1600->termination_lvd =
11127 adv_dvc_varp->cfg->termination;
11128 ep_38C1600->disc_enable =
11129 adv_dvc_varp->cfg->disc_enable;
11130 ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
11131 ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
11132 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
11133 ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
11134 ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
11135 ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
11136 ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
11137 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
11138 ep_38C1600->start_motor = adv_dvc_varp->start_motor;
11139 ep_38C1600->scsi_reset_delay =
11140 adv_dvc_varp->scsi_reset_wait;
11141 ep_38C1600->serial_number_word1 =
11142 adv_dvc_varp->cfg->serial1;
11143 ep_38C1600->serial_number_word2 =
11144 adv_dvc_varp->cfg->serial2;
11145 ep_38C1600->serial_number_word3 =
11146 adv_dvc_varp->cfg->serial3;
11147 }
11148
11149
11150
11151
11152 boardp->init_tidmask |=
11153 ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
11154 }
11155
11156
11157
11158
11159
11160
11161 shost->max_channel = 0;
11162 if (ASC_NARROW_BOARD(boardp)) {
11163 shost->max_id = ASC_MAX_TID + 1;
11164 shost->max_lun = ASC_MAX_LUN + 1;
11165 shost->max_cmd_len = ASC_MAX_CDB_LEN;
11166
11167 shost->io_port = asc_dvc_varp->iop_base;
11168 boardp->asc_n_io_port = ASC_IOADR_GAP;
11169 shost->this_id = asc_dvc_varp->cfg->chip_scsi_id;
11170
11171
11172 shost->can_queue = asc_dvc_varp->max_total_qng;
11173 } else {
11174 shost->max_id = ADV_MAX_TID + 1;
11175 shost->max_lun = ADV_MAX_LUN + 1;
11176 shost->max_cmd_len = ADV_MAX_CDB_LEN;
11177
11178
11179
11180
11181
11182
11183
11184 shost->io_port = iop;
11185
11186 shost->this_id = adv_dvc_varp->chip_scsi_id;
11187
11188
11189 shost->can_queue = adv_dvc_varp->max_host_qng;
11190 }
11191
11192
11193
11194
11195
11196 if (ASC_NARROW_BOARD(boardp)) {
11197
11198
11199
11200
11201
11202
11203 shost->sg_tablesize =
11204 (((asc_dvc_varp->max_total_qng - 2) / 2) *
11205 ASC_SG_LIST_PER_Q) + 1;
11206 } else {
11207 shost->sg_tablesize = ADV_MAX_SG_LIST;
11208 }
11209
11210
11211
11212
11213
11214
11215
11216 if (shost->sg_tablesize > SG_ALL) {
11217 shost->sg_tablesize = SG_ALL;
11218 }
11219
11220 ASC_DBG(1, "sg_tablesize: %d\n", shost->sg_tablesize);
11221
11222
11223 if (ASC_NARROW_BOARD(boardp)) {
11224 shost->base = AscGetChipBiosAddress(asc_dvc_varp->iop_base,
11225 asc_dvc_varp->bus_type);
11226 } else {
11227
11228
11229
11230
11231 AdvReadWordLram(adv_dvc_varp->iop_base,
11232 BIOS_SIGNATURE, boardp->bios_signature);
11233 AdvReadWordLram(adv_dvc_varp->iop_base,
11234 BIOS_VERSION, boardp->bios_version);
11235 AdvReadWordLram(adv_dvc_varp->iop_base,
11236 BIOS_CODESEG, boardp->bios_codeseg);
11237 AdvReadWordLram(adv_dvc_varp->iop_base,
11238 BIOS_CODELEN, boardp->bios_codelen);
11239
11240 ASC_DBG(1, "bios_signature 0x%x, bios_version 0x%x\n",
11241 boardp->bios_signature, boardp->bios_version);
11242
11243 ASC_DBG(1, "bios_codeseg 0x%x, bios_codelen 0x%x\n",
11244 boardp->bios_codeseg, boardp->bios_codelen);
11245
11246
11247
11248
11249
11250 if (boardp->bios_signature == 0x55AA) {
11251
11252
11253
11254
11255 shost->base = ((ulong)boardp->bios_codeseg << 4);
11256 } else {
11257 shost->base = 0;
11258 }
11259 }
11260
11261
11262
11263
11264
11265
11266 shost->dma_channel = NO_ISA_DMA;
11267#ifdef CONFIG_ISA
11268 if (ASC_NARROW_BOARD(boardp)) {
11269
11270 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
11271 shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
11272 ret = request_dma(shost->dma_channel, DRV_NAME);
11273 if (ret) {
11274 shost_printk(KERN_ERR, shost, "request_dma() "
11275 "%d failed %d\n",
11276 shost->dma_channel, ret);
11277 goto err_unmap;
11278 }
11279 AscEnableIsaDma(shost->dma_channel);
11280 }
11281 }
11282#endif
11283
11284
11285 ASC_DBG(2, "request_irq(%d, %p)\n", boardp->irq, shost);
11286
11287 ret = request_irq(boardp->irq, advansys_interrupt, share_irq,
11288 DRV_NAME, shost);
11289
11290 if (ret) {
11291 if (ret == -EBUSY) {
11292 shost_printk(KERN_ERR, shost, "request_irq(): IRQ 0x%x "
11293 "already in use\n", boardp->irq);
11294 } else if (ret == -EINVAL) {
11295 shost_printk(KERN_ERR, shost, "request_irq(): IRQ 0x%x "
11296 "not valid\n", boardp->irq);
11297 } else {
11298 shost_printk(KERN_ERR, shost, "request_irq(): IRQ 0x%x "
11299 "failed with %d\n", boardp->irq, ret);
11300 }
11301 goto err_free_dma;
11302 }
11303
11304
11305
11306
11307 if (ASC_NARROW_BOARD(boardp)) {
11308 ASC_DBG(2, "AscInitAsc1000Driver()\n");
11309
11310 asc_dvc_varp->overrun_buf = kzalloc(ASC_OVERRUN_BSIZE, GFP_KERNEL);
11311 if (!asc_dvc_varp->overrun_buf) {
11312 ret = -ENOMEM;
11313 goto err_free_irq;
11314 }
11315 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
11316
11317 if (warn_code || asc_dvc_varp->err_code) {
11318 shost_printk(KERN_ERR, shost, "error: init_state 0x%x, "
11319 "warn 0x%x, error 0x%x\n",
11320 asc_dvc_varp->init_state, warn_code,
11321 asc_dvc_varp->err_code);
11322 if (!asc_dvc_varp->overrun_dma) {
11323 ret = -ENODEV;
11324 goto err_free_mem;
11325 }
11326 }
11327 } else {
11328 if (advansys_wide_init_chip(shost)) {
11329 ret = -ENODEV;
11330 goto err_free_mem;
11331 }
11332 }
11333
11334 ASC_DBG_PRT_SCSI_HOST(2, shost);
11335
11336 ret = scsi_add_host(shost, boardp->dev);
11337 if (ret)
11338 goto err_free_mem;
11339
11340 scsi_scan_host(shost);
11341 return 0;
11342
11343 err_free_mem:
11344 if (ASC_NARROW_BOARD(boardp)) {
11345 if (asc_dvc_varp->overrun_dma)
11346 dma_unmap_single(boardp->dev, asc_dvc_varp->overrun_dma,
11347 ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE);
11348 kfree(asc_dvc_varp->overrun_buf);
11349 } else
11350 advansys_wide_free_mem(boardp);
11351 err_free_irq:
11352 free_irq(boardp->irq, shost);
11353 err_free_dma:
11354#ifdef CONFIG_ISA
11355 if (shost->dma_channel != NO_ISA_DMA)
11356 free_dma(shost->dma_channel);
11357#endif
11358 err_unmap:
11359 if (boardp->ioremap_addr)
11360 iounmap(boardp->ioremap_addr);
11361#ifdef CONFIG_PCI
11362 err_shost:
11363#endif
11364 return ret;
11365}
11366
11367
11368
11369
11370
11371
11372static int advansys_release(struct Scsi_Host *shost)
11373{
11374 struct asc_board *board = shost_priv(shost);
11375 ASC_DBG(1, "begin\n");
11376 scsi_remove_host(shost);
11377 free_irq(board->irq, shost);
11378#ifdef CONFIG_ISA
11379 if (shost->dma_channel != NO_ISA_DMA) {
11380 ASC_DBG(1, "free_dma()\n");
11381 free_dma(shost->dma_channel);
11382 }
11383#endif
11384 if (ASC_NARROW_BOARD(board)) {
11385 dma_unmap_single(board->dev,
11386 board->dvc_var.asc_dvc_var.overrun_dma,
11387 ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE);
11388 kfree(board->dvc_var.asc_dvc_var.overrun_buf);
11389 } else {
11390 iounmap(board->ioremap_addr);
11391 advansys_wide_free_mem(board);
11392 }
11393 scsi_host_put(shost);
11394 ASC_DBG(1, "end\n");
11395 return 0;
11396}
11397
11398#define ASC_IOADR_TABLE_MAX_IX 11
11399
11400static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] = {
11401 0x100, 0x0110, 0x120, 0x0130, 0x140, 0x0150, 0x0190,
11402 0x0210, 0x0230, 0x0250, 0x0330
11403};
11404
11405
11406
11407
11408
11409
11410
11411
11412static unsigned int advansys_isa_irq_no(PortAddr iop_base)
11413{
11414 unsigned short cfg_lsw = AscGetChipCfgLsw(iop_base);
11415 unsigned int chip_irq = ((cfg_lsw >> 2) & 0x03) + 10;
11416 if (chip_irq == 13)
11417 chip_irq = 15;
11418 return chip_irq;
11419}
11420
11421static int advansys_isa_probe(struct device *dev, unsigned int id)
11422{
11423 int err = -ENODEV;
11424 PortAddr iop_base = _asc_def_iop_base[id];
11425 struct Scsi_Host *shost;
11426 struct asc_board *board;
11427
11428 if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) {
11429 ASC_DBG(1, "I/O port 0x%x busy\n", iop_base);
11430 return -ENODEV;
11431 }
11432 ASC_DBG(1, "probing I/O port 0x%x\n", iop_base);
11433 if (!AscFindSignature(iop_base))
11434 goto release_region;
11435 if (!(AscGetChipVersion(iop_base, ASC_IS_ISA) & ASC_CHIP_VER_ISA_BIT))
11436 goto release_region;
11437
11438 err = -ENOMEM;
11439 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
11440 if (!shost)
11441 goto release_region;
11442
11443 board = shost_priv(shost);
11444 board->irq = advansys_isa_irq_no(iop_base);
11445 board->dev = dev;
11446 board->shost = shost;
11447
11448 err = advansys_board_found(shost, iop_base, ASC_IS_ISA);
11449 if (err)
11450 goto free_host;
11451
11452 dev_set_drvdata(dev, shost);
11453 return 0;
11454
11455 free_host:
11456 scsi_host_put(shost);
11457 release_region:
11458 release_region(iop_base, ASC_IOADR_GAP);
11459 return err;
11460}
11461
11462static int advansys_isa_remove(struct device *dev, unsigned int id)
11463{
11464 int ioport = _asc_def_iop_base[id];
11465 advansys_release(dev_get_drvdata(dev));
11466 release_region(ioport, ASC_IOADR_GAP);
11467 return 0;
11468}
11469
11470static struct isa_driver advansys_isa_driver = {
11471 .probe = advansys_isa_probe,
11472 .remove = advansys_isa_remove,
11473 .driver = {
11474 .owner = THIS_MODULE,
11475 .name = DRV_NAME,
11476 },
11477};
11478
11479
11480
11481
11482
11483
11484
11485
11486
11487
11488
11489
11490static unsigned int advansys_vlb_irq_no(PortAddr iop_base)
11491{
11492 unsigned short cfg_lsw = AscGetChipCfgLsw(iop_base);
11493 unsigned int chip_irq = ((cfg_lsw >> 2) & 0x07) + 9;
11494 if ((chip_irq < 10) || (chip_irq == 13) || (chip_irq > 15))
11495 return 0;
11496 return chip_irq;
11497}
11498
11499static int advansys_vlb_probe(struct device *dev, unsigned int id)
11500{
11501 int err = -ENODEV;
11502 PortAddr iop_base = _asc_def_iop_base[id];
11503 struct Scsi_Host *shost;
11504 struct asc_board *board;
11505
11506 if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) {
11507 ASC_DBG(1, "I/O port 0x%x busy\n", iop_base);
11508 return -ENODEV;
11509 }
11510 ASC_DBG(1, "probing I/O port 0x%x\n", iop_base);
11511 if (!AscFindSignature(iop_base))
11512 goto release_region;
11513
11514
11515
11516
11517
11518 if (AscGetChipVersion(iop_base, ASC_IS_VL) > ASC_CHIP_MAX_VER_VL)
11519 goto release_region;
11520
11521 err = -ENOMEM;
11522 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
11523 if (!shost)
11524 goto release_region;
11525
11526 board = shost_priv(shost);
11527 board->irq = advansys_vlb_irq_no(iop_base);
11528 board->dev = dev;
11529 board->shost = shost;
11530
11531 err = advansys_board_found(shost, iop_base, ASC_IS_VL);
11532 if (err)
11533 goto free_host;
11534
11535 dev_set_drvdata(dev, shost);
11536 return 0;
11537
11538 free_host:
11539 scsi_host_put(shost);
11540 release_region:
11541 release_region(iop_base, ASC_IOADR_GAP);
11542 return -ENODEV;
11543}
11544
11545static struct isa_driver advansys_vlb_driver = {
11546 .probe = advansys_vlb_probe,
11547 .remove = advansys_isa_remove,
11548 .driver = {
11549 .owner = THIS_MODULE,
11550 .name = "advansys_vlb",
11551 },
11552};
11553
11554static struct eisa_device_id advansys_eisa_table[] = {
11555 { "ABP7401" },
11556 { "ABP7501" },
11557 { "" }
11558};
11559
11560MODULE_DEVICE_TABLE(eisa, advansys_eisa_table);
11561
11562
11563
11564
11565
11566struct eisa_scsi_data {
11567 struct Scsi_Host *host[2];
11568};
11569
11570
11571
11572
11573
11574
11575
11576
11577
11578
11579
11580
11581static unsigned int advansys_eisa_irq_no(struct eisa_device *edev)
11582{
11583 unsigned short cfg_lsw = inw(edev->base_addr + 0xc86);
11584 unsigned int chip_irq = ((cfg_lsw >> 8) & 0x07) + 10;
11585 if ((chip_irq == 13) || (chip_irq > 15))
11586 return 0;
11587 return chip_irq;
11588}
11589
11590static int advansys_eisa_probe(struct device *dev)
11591{
11592 int i, ioport, irq = 0;
11593 int err;
11594 struct eisa_device *edev = to_eisa_device(dev);
11595 struct eisa_scsi_data *data;
11596
11597 err = -ENOMEM;
11598 data = kzalloc(sizeof(*data), GFP_KERNEL);
11599 if (!data)
11600 goto fail;
11601 ioport = edev->base_addr + 0xc30;
11602
11603 err = -ENODEV;
11604 for (i = 0; i < 2; i++, ioport += 0x20) {
11605 struct asc_board *board;
11606 struct Scsi_Host *shost;
11607 if (!request_region(ioport, ASC_IOADR_GAP, DRV_NAME)) {
11608 printk(KERN_WARNING "Region %x-%x busy\n", ioport,
11609 ioport + ASC_IOADR_GAP - 1);
11610 continue;
11611 }
11612 if (!AscFindSignature(ioport)) {
11613 release_region(ioport, ASC_IOADR_GAP);
11614 continue;
11615 }
11616
11617
11618
11619
11620
11621
11622
11623
11624 inw(ioport + 4);
11625
11626 if (!irq)
11627 irq = advansys_eisa_irq_no(edev);
11628
11629 err = -ENOMEM;
11630 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
11631 if (!shost)
11632 goto release_region;
11633
11634 board = shost_priv(shost);
11635 board->irq = irq;
11636 board->dev = dev;
11637 board->shost = shost;
11638
11639 err = advansys_board_found(shost, ioport, ASC_IS_EISA);
11640 if (!err) {
11641 data->host[i] = shost;
11642 continue;
11643 }
11644
11645 scsi_host_put(shost);
11646 release_region:
11647 release_region(ioport, ASC_IOADR_GAP);
11648 break;
11649 }
11650
11651 if (err)
11652 goto free_data;
11653 dev_set_drvdata(dev, data);
11654 return 0;
11655
11656 free_data:
11657 kfree(data->host[0]);
11658 kfree(data->host[1]);
11659 kfree(data);
11660 fail:
11661 return err;
11662}
11663
11664static int advansys_eisa_remove(struct device *dev)
11665{
11666 int i;
11667 struct eisa_scsi_data *data = dev_get_drvdata(dev);
11668
11669 for (i = 0; i < 2; i++) {
11670 int ioport;
11671 struct Scsi_Host *shost = data->host[i];
11672 if (!shost)
11673 continue;
11674 ioport = shost->io_port;
11675 advansys_release(shost);
11676 release_region(ioport, ASC_IOADR_GAP);
11677 }
11678
11679 kfree(data);
11680 return 0;
11681}
11682
11683static struct eisa_driver advansys_eisa_driver = {
11684 .id_table = advansys_eisa_table,
11685 .driver = {
11686 .name = DRV_NAME,
11687 .probe = advansys_eisa_probe,
11688 .remove = advansys_eisa_remove,
11689 }
11690};
11691
11692
11693static struct pci_device_id advansys_pci_tbl[] = {
11694 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A,
11695 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
11696 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940,
11697 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
11698 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940U,
11699 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
11700 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940UW,
11701 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
11702 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C0800_REV1,
11703 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
11704 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C1600_REV1,
11705 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
11706 {}
11707};
11708
11709MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);
11710
11711static void advansys_set_latency(struct pci_dev *pdev)
11712{
11713 if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
11714 (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
11715 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0);
11716 } else {
11717 u8 latency;
11718 pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency);
11719 if (latency < 0x20)
11720 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x20);
11721 }
11722}
11723
11724static int advansys_pci_probe(struct pci_dev *pdev,
11725 const struct pci_device_id *ent)
11726{
11727 int err, ioport;
11728 struct Scsi_Host *shost;
11729 struct asc_board *board;
11730
11731 err = pci_enable_device(pdev);
11732 if (err)
11733 goto fail;
11734 err = pci_request_regions(pdev, DRV_NAME);
11735 if (err)
11736 goto disable_device;
11737 pci_set_master(pdev);
11738 advansys_set_latency(pdev);
11739
11740 err = -ENODEV;
11741 if (pci_resource_len(pdev, 0) == 0)
11742 goto release_region;
11743
11744 ioport = pci_resource_start(pdev, 0);
11745
11746 err = -ENOMEM;
11747 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
11748 if (!shost)
11749 goto release_region;
11750
11751 board = shost_priv(shost);
11752 board->irq = pdev->irq;
11753 board->dev = &pdev->dev;
11754 board->shost = shost;
11755
11756 if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW ||
11757 pdev->device == PCI_DEVICE_ID_38C0800_REV1 ||
11758 pdev->device == PCI_DEVICE_ID_38C1600_REV1) {
11759 board->flags |= ASC_IS_WIDE_BOARD;
11760 }
11761
11762 err = advansys_board_found(shost, ioport, ASC_IS_PCI);
11763 if (err)
11764 goto free_host;
11765
11766 pci_set_drvdata(pdev, shost);
11767 return 0;
11768
11769 free_host:
11770 scsi_host_put(shost);
11771 release_region:
11772 pci_release_regions(pdev);
11773 disable_device:
11774 pci_disable_device(pdev);
11775 fail:
11776 return err;
11777}
11778
11779static void advansys_pci_remove(struct pci_dev *pdev)
11780{
11781 advansys_release(pci_get_drvdata(pdev));
11782 pci_release_regions(pdev);
11783 pci_disable_device(pdev);
11784}
11785
11786static struct pci_driver advansys_pci_driver = {
11787 .name = DRV_NAME,
11788 .id_table = advansys_pci_tbl,
11789 .probe = advansys_pci_probe,
11790 .remove = advansys_pci_remove,
11791};
11792
11793static int __init advansys_init(void)
11794{
11795 int error;
11796
11797 error = isa_register_driver(&advansys_isa_driver,
11798 ASC_IOADR_TABLE_MAX_IX);
11799 if (error)
11800 goto fail;
11801
11802 error = isa_register_driver(&advansys_vlb_driver,
11803 ASC_IOADR_TABLE_MAX_IX);
11804 if (error)
11805 goto unregister_isa;
11806
11807 error = eisa_driver_register(&advansys_eisa_driver);
11808 if (error)
11809 goto unregister_vlb;
11810
11811 error = pci_register_driver(&advansys_pci_driver);
11812 if (error)
11813 goto unregister_eisa;
11814
11815 return 0;
11816
11817 unregister_eisa:
11818 eisa_driver_unregister(&advansys_eisa_driver);
11819 unregister_vlb:
11820 isa_unregister_driver(&advansys_vlb_driver);
11821 unregister_isa:
11822 isa_unregister_driver(&advansys_isa_driver);
11823 fail:
11824 return error;
11825}
11826
11827static void __exit advansys_exit(void)
11828{
11829 pci_unregister_driver(&advansys_pci_driver);
11830 eisa_driver_unregister(&advansys_eisa_driver);
11831 isa_unregister_driver(&advansys_vlb_driver);
11832 isa_unregister_driver(&advansys_isa_driver);
11833}
11834
11835module_init(advansys_init);
11836module_exit(advansys_exit);
11837
11838MODULE_LICENSE("GPL");
11839MODULE_FIRMWARE("advansys/mcode.bin");
11840MODULE_FIRMWARE("advansys/3550.bin");
11841MODULE_FIRMWARE("advansys/38C0800.bin");
11842MODULE_FIRMWARE("advansys/38C1600.bin");
11843