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