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 adv_req_t *reqp;
5953 adv_sgblk_t *sgblkp;
5954 struct scsi_cmnd *scp;
5955 u32 resid_cnt;
5956 dma_addr_t sense_addr;
5957
5958 ASC_DBG(1, "adv_dvc_varp 0x%p, scsiqp 0x%p\n",
5959 adv_dvc_varp, scsiqp);
5960 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
5961
5962
5963
5964
5965
5966
5967 scp = scsi_host_find_tag(boardp->shost, scsiqp->srb_tag);
5968
5969 ASC_DBG(1, "scp 0x%p\n", scp);
5970 if (scp == NULL) {
5971 ASC_PRINT
5972 ("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
5973 return;
5974 }
5975 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
5976
5977 reqp = (adv_req_t *)scp->host_scribble;
5978 ASC_DBG(1, "reqp 0x%lx\n", (ulong)reqp);
5979 if (reqp == NULL) {
5980 ASC_PRINT("adv_isr_callback: reqp is NULL\n");
5981 return;
5982 }
5983
5984
5985
5986
5987 scp->host_scribble = NULL;
5988 reqp->cmndp = NULL;
5989
5990 ASC_STATS(boardp->shost, callback);
5991 ASC_DBG(1, "shost 0x%p\n", boardp->shost);
5992
5993 sense_addr = le32_to_cpu(scsiqp->sense_addr);
5994 dma_unmap_single(boardp->dev, sense_addr,
5995 SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
5996
5997
5998
5999
6000 switch (scsiqp->done_status) {
6001 case QD_NO_ERROR:
6002 ASC_DBG(2, "QD_NO_ERROR\n");
6003 scp->result = 0;
6004
6005
6006
6007
6008
6009
6010
6011 resid_cnt = le32_to_cpu(scsiqp->data_cnt);
6012 if (scsi_bufflen(scp) != 0 && resid_cnt != 0 &&
6013 resid_cnt <= scsi_bufflen(scp)) {
6014 ASC_DBG(1, "underrun condition %lu bytes\n",
6015 (ulong)resid_cnt);
6016 scsi_set_resid(scp, resid_cnt);
6017 }
6018 break;
6019
6020 case QD_WITH_ERROR:
6021 ASC_DBG(2, "QD_WITH_ERROR\n");
6022 switch (scsiqp->host_status) {
6023 case QHSTA_NO_ERROR:
6024 if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
6025 ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n");
6026 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
6027 SCSI_SENSE_BUFFERSIZE);
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
6041 STATUS_BYTE(scsiqp->scsi_status);
6042 } else {
6043 scp->result = STATUS_BYTE(scsiqp->scsi_status);
6044 }
6045 break;
6046
6047 default:
6048
6049 ASC_DBG(1, "host_status 0x%x\n", scsiqp->host_status);
6050 scp->result = HOST_BYTE(DID_BAD_TARGET);
6051 break;
6052 }
6053 break;
6054
6055 case QD_ABORTED_BY_HOST:
6056 ASC_DBG(1, "QD_ABORTED_BY_HOST\n");
6057 scp->result =
6058 HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
6059 break;
6060
6061 default:
6062 ASC_DBG(1, "done_status 0x%x\n", scsiqp->done_status);
6063 scp->result =
6064 HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
6065 break;
6066 }
6067
6068
6069
6070
6071
6072
6073 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
6074 scsiqp->done_status == QD_NO_ERROR &&
6075 scsiqp->host_status == QHSTA_NO_ERROR) {
6076 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
6077 }
6078
6079 asc_scsi_done(scp);
6080
6081
6082
6083
6084 while ((sgblkp = reqp->sgblkp) != NULL) {
6085
6086 reqp->sgblkp = sgblkp->next_sgblkp;
6087
6088 dma_pool_free(boardp->adv_sgblk_pool, sgblkp,
6089 sgblkp->sg_addr);
6090 }
6091
6092 ASC_DBG(1, "done\n");
6093}
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114static int AdvISR(ADV_DVC_VAR *asc_dvc)
6115{
6116 AdvPortAddr iop_base;
6117 uchar int_stat;
6118 ushort target_bit;
6119 ADV_CARR_T *free_carrp;
6120 __le32 irq_next_vpa;
6121 ADV_SCSI_REQ_Q *scsiq;
6122 adv_req_t *reqp;
6123
6124 iop_base = asc_dvc->iop_base;
6125
6126
6127 int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
6128
6129 if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
6130 ADV_INTR_STATUS_INTRC)) == 0) {
6131 return ADV_FALSE;
6132 }
6133
6134
6135
6136
6137
6138
6139 if (int_stat & ADV_INTR_STATUS_INTRB) {
6140 uchar intrb_code;
6141
6142 AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
6143
6144 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
6145 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
6146 if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
6147 asc_dvc->carr_pending_cnt != 0) {
6148 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
6149 ADV_TICKLE_A);
6150 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
6151 AdvWriteByteRegister(iop_base,
6152 IOPB_TICKLE,
6153 ADV_TICKLE_NOP);
6154 }
6155 }
6156 }
6157
6158 adv_async_callback(asc_dvc, intrb_code);
6159 }
6160
6161
6162
6163
6164 while (((irq_next_vpa =
6165 le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ADV_RQ_DONE) != 0) {
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175 u32 pa_offset = le32_to_cpu(asc_dvc->irq_sp->areq_vpa);
6176 ASC_DBG(1, "irq_sp %p areq_vpa %u\n",
6177 asc_dvc->irq_sp, pa_offset);
6178 reqp = adv_get_reqp(asc_dvc, pa_offset);
6179 scsiq = &reqp->scsi_req_q;
6180
6181
6182
6183
6184
6185
6186 if ((irq_next_vpa & ADV_RQ_GOOD) != 0) {
6187 scsiq->done_status = QD_NO_ERROR;
6188 scsiq->host_status = scsiq->scsi_status = 0;
6189 scsiq->data_cnt = 0L;
6190 }
6191
6192
6193
6194
6195
6196
6197 free_carrp = asc_dvc->irq_sp;
6198 asc_dvc->irq_sp = adv_get_carrier(asc_dvc,
6199 ADV_GET_CARRP(irq_next_vpa));
6200
6201 free_carrp->next_vpa = asc_dvc->carr_freelist->carr_va;
6202 asc_dvc->carr_freelist = free_carrp;
6203 asc_dvc->carr_pending_cnt--;
6204
6205 target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
6206
6207
6208
6209
6210 scsiq->cntl = 0;
6211
6212
6213
6214
6215
6216 adv_isr_callback(asc_dvc, scsiq);
6217
6218
6219
6220
6221
6222
6223
6224 }
6225 return ADV_TRUE;
6226}
6227
6228static int AscSetLibErrorCode(ASC_DVC_VAR *asc_dvc, ushort err_code)
6229{
6230 if (asc_dvc->err_code == 0) {
6231 asc_dvc->err_code = err_code;
6232 AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
6233 err_code);
6234 }
6235 return err_code;
6236}
6237
6238static void AscAckInterrupt(PortAddr iop_base)
6239{
6240 uchar host_flag;
6241 uchar risc_flag;
6242 ushort loop;
6243
6244 loop = 0;
6245 do {
6246 risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
6247 if (loop++ > 0x7FFF) {
6248 break;
6249 }
6250 } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
6251 host_flag =
6252 AscReadLramByte(iop_base,
6253 ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
6254 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
6255 (uchar)(host_flag | ASC_HOST_FLAG_ACK_INT));
6256 AscSetChipStatus(iop_base, CIW_INT_ACK);
6257 loop = 0;
6258 while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
6259 AscSetChipStatus(iop_base, CIW_INT_ACK);
6260 if (loop++ > 3) {
6261 break;
6262 }
6263 }
6264 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
6265}
6266
6267static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time)
6268{
6269 const uchar *period_table;
6270 int max_index;
6271 int min_index;
6272 int i;
6273
6274 period_table = asc_dvc->sdtr_period_tbl;
6275 max_index = (int)asc_dvc->max_sdtr_index;
6276 min_index = (int)asc_dvc->min_sdtr_index;
6277 if ((syn_time <= period_table[max_index])) {
6278 for (i = min_index; i < (max_index - 1); i++) {
6279 if (syn_time <= period_table[i]) {
6280 return (uchar)i;
6281 }
6282 }
6283 return (uchar)max_index;
6284 } else {
6285 return (uchar)(max_index + 1);
6286 }
6287}
6288
6289static uchar
6290AscMsgOutSDTR(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar sdtr_offset)
6291{
6292 PortAddr iop_base = asc_dvc->iop_base;
6293 uchar sdtr_period_index = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
6294 EXT_MSG sdtr_buf = {
6295 .msg_type = EXTENDED_MESSAGE,
6296 .msg_len = MS_SDTR_LEN,
6297 .msg_req = EXTENDED_SDTR,
6298 .xfer_period = sdtr_period,
6299 .req_ack_offset = sdtr_offset,
6300 };
6301 sdtr_offset &= ASC_SYN_MAX_OFFSET;
6302
6303 if (sdtr_period_index <= asc_dvc->max_sdtr_index) {
6304 AscMemWordCopyPtrToLram(iop_base, ASCV_MSGOUT_BEG,
6305 (uchar *)&sdtr_buf,
6306 sizeof(EXT_MSG) >> 1);
6307 return ((sdtr_period_index << 4) | sdtr_offset);
6308 } else {
6309 sdtr_buf.req_ack_offset = 0;
6310 AscMemWordCopyPtrToLram(iop_base, ASCV_MSGOUT_BEG,
6311 (uchar *)&sdtr_buf,
6312 sizeof(EXT_MSG) >> 1);
6313 return 0;
6314 }
6315}
6316
6317static uchar
6318AscCalSDTRData(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar syn_offset)
6319{
6320 uchar byte;
6321 uchar sdtr_period_ix;
6322
6323 sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
6324 if (sdtr_period_ix > asc_dvc->max_sdtr_index)
6325 return 0xFF;
6326 byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
6327 return byte;
6328}
6329
6330static bool AscSetChipSynRegAtID(PortAddr iop_base, uchar id, uchar sdtr_data)
6331{
6332 ASC_SCSI_BIT_ID_TYPE org_id;
6333 int i;
6334 bool sta = true;
6335
6336 AscSetBank(iop_base, 1);
6337 org_id = AscReadChipDvcID(iop_base);
6338 for (i = 0; i <= ASC_MAX_TID; i++) {
6339 if (org_id == (0x01 << i))
6340 break;
6341 }
6342 org_id = (ASC_SCSI_BIT_ID_TYPE) i;
6343 AscWriteChipDvcID(iop_base, id);
6344 if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
6345 AscSetBank(iop_base, 0);
6346 AscSetChipSyn(iop_base, sdtr_data);
6347 if (AscGetChipSyn(iop_base) != sdtr_data) {
6348 sta = false;
6349 }
6350 } else {
6351 sta = false;
6352 }
6353 AscSetBank(iop_base, 1);
6354 AscWriteChipDvcID(iop_base, org_id);
6355 AscSetBank(iop_base, 0);
6356 return (sta);
6357}
6358
6359static void AscSetChipSDTR(PortAddr iop_base, uchar sdtr_data, uchar tid_no)
6360{
6361 AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
6362 AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
6363}
6364
6365static void AscIsrChipHalted(ASC_DVC_VAR *asc_dvc)
6366{
6367 EXT_MSG ext_msg;
6368 EXT_MSG out_msg;
6369 ushort halt_q_addr;
6370 bool sdtr_accept;
6371 ushort int_halt_code;
6372 ASC_SCSI_BIT_ID_TYPE scsi_busy;
6373 ASC_SCSI_BIT_ID_TYPE target_id;
6374 PortAddr iop_base;
6375 uchar tag_code;
6376 uchar q_status;
6377 uchar halt_qp;
6378 uchar sdtr_data;
6379 uchar target_ix;
6380 uchar q_cntl, tid_no;
6381 uchar cur_dvc_qng;
6382 uchar asyn_sdtr;
6383 uchar scsi_status;
6384 struct asc_board *boardp;
6385
6386 BUG_ON(!asc_dvc->drv_ptr);
6387 boardp = asc_dvc->drv_ptr;
6388
6389 iop_base = asc_dvc->iop_base;
6390 int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
6391
6392 halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
6393 halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
6394 target_ix = AscReadLramByte(iop_base,
6395 (ushort)(halt_q_addr +
6396 (ushort)ASC_SCSIQ_B_TARGET_IX));
6397 q_cntl = AscReadLramByte(iop_base,
6398 (ushort)(halt_q_addr + (ushort)ASC_SCSIQ_B_CNTL));
6399 tid_no = ASC_TIX_TO_TID(target_ix);
6400 target_id = (uchar)ASC_TID_TO_TARGET_ID(tid_no);
6401 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
6402 asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
6403 } else {
6404 asyn_sdtr = 0;
6405 }
6406 if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
6407 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
6408 AscSetChipSDTR(iop_base, 0, tid_no);
6409 boardp->sdtr_data[tid_no] = 0;
6410 }
6411 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6412 return;
6413 } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
6414 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
6415 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
6416 boardp->sdtr_data[tid_no] = asyn_sdtr;
6417 }
6418 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6419 return;
6420 } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
6421 AscMemWordCopyPtrFromLram(iop_base,
6422 ASCV_MSGIN_BEG,
6423 (uchar *)&ext_msg,
6424 sizeof(EXT_MSG) >> 1);
6425
6426 if (ext_msg.msg_type == EXTENDED_MESSAGE &&
6427 ext_msg.msg_req == EXTENDED_SDTR &&
6428 ext_msg.msg_len == MS_SDTR_LEN) {
6429 sdtr_accept = true;
6430 if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
6431
6432 sdtr_accept = false;
6433 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
6434 }
6435 if ((ext_msg.xfer_period <
6436 asc_dvc->sdtr_period_tbl[asc_dvc->min_sdtr_index])
6437 || (ext_msg.xfer_period >
6438 asc_dvc->sdtr_period_tbl[asc_dvc->
6439 max_sdtr_index])) {
6440 sdtr_accept = false;
6441 ext_msg.xfer_period =
6442 asc_dvc->sdtr_period_tbl[asc_dvc->
6443 min_sdtr_index];
6444 }
6445 if (sdtr_accept) {
6446 sdtr_data =
6447 AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
6448 ext_msg.req_ack_offset);
6449 if (sdtr_data == 0xFF) {
6450
6451 q_cntl |= QC_MSG_OUT;
6452 asc_dvc->init_sdtr &= ~target_id;
6453 asc_dvc->sdtr_done &= ~target_id;
6454 AscSetChipSDTR(iop_base, asyn_sdtr,
6455 tid_no);
6456 boardp->sdtr_data[tid_no] = asyn_sdtr;
6457 }
6458 }
6459 if (ext_msg.req_ack_offset == 0) {
6460
6461 q_cntl &= ~QC_MSG_OUT;
6462 asc_dvc->init_sdtr &= ~target_id;
6463 asc_dvc->sdtr_done &= ~target_id;
6464 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
6465 } else {
6466 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
6467 q_cntl &= ~QC_MSG_OUT;
6468 asc_dvc->sdtr_done |= target_id;
6469 asc_dvc->init_sdtr |= target_id;
6470 asc_dvc->pci_fix_asyn_xfer &=
6471 ~target_id;
6472 sdtr_data =
6473 AscCalSDTRData(asc_dvc,
6474 ext_msg.xfer_period,
6475 ext_msg.
6476 req_ack_offset);
6477 AscSetChipSDTR(iop_base, sdtr_data,
6478 tid_no);
6479 boardp->sdtr_data[tid_no] = sdtr_data;
6480 } else {
6481 q_cntl |= QC_MSG_OUT;
6482 AscMsgOutSDTR(asc_dvc,
6483 ext_msg.xfer_period,
6484 ext_msg.req_ack_offset);
6485 asc_dvc->pci_fix_asyn_xfer &=
6486 ~target_id;
6487 sdtr_data =
6488 AscCalSDTRData(asc_dvc,
6489 ext_msg.xfer_period,
6490 ext_msg.
6491 req_ack_offset);
6492 AscSetChipSDTR(iop_base, sdtr_data,
6493 tid_no);
6494 boardp->sdtr_data[tid_no] = sdtr_data;
6495 asc_dvc->sdtr_done |= target_id;
6496 asc_dvc->init_sdtr |= target_id;
6497 }
6498 }
6499
6500 AscWriteLramByte(iop_base,
6501 (ushort)(halt_q_addr +
6502 (ushort)ASC_SCSIQ_B_CNTL),
6503 q_cntl);
6504 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6505 return;
6506 } else if (ext_msg.msg_type == EXTENDED_MESSAGE &&
6507 ext_msg.msg_req == EXTENDED_WDTR &&
6508 ext_msg.msg_len == MS_WDTR_LEN) {
6509
6510 ext_msg.wdtr_width = 0;
6511 AscMemWordCopyPtrToLram(iop_base,
6512 ASCV_MSGOUT_BEG,
6513 (uchar *)&ext_msg,
6514 sizeof(EXT_MSG) >> 1);
6515 q_cntl |= QC_MSG_OUT;
6516 AscWriteLramByte(iop_base,
6517 (ushort)(halt_q_addr +
6518 (ushort)ASC_SCSIQ_B_CNTL),
6519 q_cntl);
6520 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6521 return;
6522 } else {
6523
6524 ext_msg.msg_type = MESSAGE_REJECT;
6525 AscMemWordCopyPtrToLram(iop_base,
6526 ASCV_MSGOUT_BEG,
6527 (uchar *)&ext_msg,
6528 sizeof(EXT_MSG) >> 1);
6529 q_cntl |= QC_MSG_OUT;
6530 AscWriteLramByte(iop_base,
6531 (ushort)(halt_q_addr +
6532 (ushort)ASC_SCSIQ_B_CNTL),
6533 q_cntl);
6534 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6535 return;
6536 }
6537 } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
6538
6539 q_cntl |= QC_REQ_SENSE;
6540
6541 if ((asc_dvc->init_sdtr & target_id) != 0) {
6542
6543 asc_dvc->sdtr_done &= ~target_id;
6544
6545 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
6546 q_cntl |= QC_MSG_OUT;
6547 AscMsgOutSDTR(asc_dvc,
6548 asc_dvc->
6549 sdtr_period_tbl[(sdtr_data >> 4) &
6550 (uchar)(asc_dvc->
6551 max_sdtr_index -
6552 1)],
6553 (uchar)(sdtr_data & (uchar)
6554 ASC_SYN_MAX_OFFSET));
6555 }
6556
6557 AscWriteLramByte(iop_base,
6558 (ushort)(halt_q_addr +
6559 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
6560
6561 tag_code = AscReadLramByte(iop_base,
6562 (ushort)(halt_q_addr + (ushort)
6563 ASC_SCSIQ_B_TAG_CODE));
6564 tag_code &= 0xDC;
6565 if ((asc_dvc->pci_fix_asyn_xfer & target_id)
6566 && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
6567 ) {
6568
6569 tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
6570 | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
6571
6572 }
6573 AscWriteLramByte(iop_base,
6574 (ushort)(halt_q_addr +
6575 (ushort)ASC_SCSIQ_B_TAG_CODE),
6576 tag_code);
6577
6578 q_status = AscReadLramByte(iop_base,
6579 (ushort)(halt_q_addr + (ushort)
6580 ASC_SCSIQ_B_STATUS));
6581 q_status |= (QS_READY | QS_BUSY);
6582 AscWriteLramByte(iop_base,
6583 (ushort)(halt_q_addr +
6584 (ushort)ASC_SCSIQ_B_STATUS),
6585 q_status);
6586
6587 scsi_busy = AscReadLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B);
6588 scsi_busy &= ~target_id;
6589 AscWriteLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B, scsi_busy);
6590
6591 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6592 return;
6593 } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
6594
6595 AscMemWordCopyPtrFromLram(iop_base,
6596 ASCV_MSGOUT_BEG,
6597 (uchar *)&out_msg,
6598 sizeof(EXT_MSG) >> 1);
6599
6600 if ((out_msg.msg_type == EXTENDED_MESSAGE) &&
6601 (out_msg.msg_len == MS_SDTR_LEN) &&
6602 (out_msg.msg_req == EXTENDED_SDTR)) {
6603
6604 asc_dvc->init_sdtr &= ~target_id;
6605 asc_dvc->sdtr_done &= ~target_id;
6606 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
6607 boardp->sdtr_data[tid_no] = asyn_sdtr;
6608 }
6609 q_cntl &= ~QC_MSG_OUT;
6610 AscWriteLramByte(iop_base,
6611 (ushort)(halt_q_addr +
6612 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
6613 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6614 return;
6615 } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
6616
6617 scsi_status = AscReadLramByte(iop_base,
6618 (ushort)((ushort)halt_q_addr +
6619 (ushort)
6620 ASC_SCSIQ_SCSI_STATUS));
6621 cur_dvc_qng =
6622 AscReadLramByte(iop_base,
6623 (ushort)((ushort)ASC_QADR_BEG +
6624 (ushort)target_ix));
6625 if ((cur_dvc_qng > 0) && (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
6626
6627 scsi_busy = AscReadLramByte(iop_base,
6628 (ushort)ASCV_SCSIBUSY_B);
6629 scsi_busy |= target_id;
6630 AscWriteLramByte(iop_base,
6631 (ushort)ASCV_SCSIBUSY_B, scsi_busy);
6632 asc_dvc->queue_full_or_busy |= target_id;
6633
6634 if (scsi_status == SAM_STAT_TASK_SET_FULL) {
6635 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
6636 cur_dvc_qng -= 1;
6637 asc_dvc->max_dvc_qng[tid_no] =
6638 cur_dvc_qng;
6639
6640 AscWriteLramByte(iop_base,
6641 (ushort)((ushort)
6642 ASCV_MAX_DVC_QNG_BEG
6643 + (ushort)
6644 tid_no),
6645 cur_dvc_qng);
6646
6647
6648
6649
6650
6651
6652 boardp->queue_full |= target_id;
6653 boardp->queue_full_cnt[tid_no] =
6654 cur_dvc_qng;
6655 }
6656 }
6657 }
6658 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6659 return;
6660 }
6661 return;
6662}
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674static void
6675DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
6676{
6677 int i;
6678 ushort word;
6679
6680 AscSetChipLramAddr(iop_base, s_addr);
6681 for (i = 0; i < 2 * words; i += 2) {
6682 if (i == 10) {
6683 continue;
6684 }
6685 word = inpw(iop_base + IOP_RAM_DATA);
6686 inbuf[i] = word & 0xff;
6687 inbuf[i + 1] = (word >> 8) & 0xff;
6688 }
6689 ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
6690}
6691
6692static uchar
6693_AscCopyLramScsiDoneQ(PortAddr iop_base,
6694 ushort q_addr,
6695 ASC_QDONE_INFO *scsiq, unsigned int max_dma_count)
6696{
6697 ushort _val;
6698 uchar sg_queue_cnt;
6699
6700 DvcGetQinfo(iop_base,
6701 q_addr + ASC_SCSIQ_DONE_INFO_BEG,
6702 (uchar *)scsiq,
6703 (sizeof(ASC_SCSIQ_2) + sizeof(ASC_SCSIQ_3)) / 2);
6704
6705 _val = AscReadLramWord(iop_base,
6706 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS));
6707 scsiq->q_status = (uchar)_val;
6708 scsiq->q_no = (uchar)(_val >> 8);
6709 _val = AscReadLramWord(iop_base,
6710 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_CNTL));
6711 scsiq->cntl = (uchar)_val;
6712 sg_queue_cnt = (uchar)(_val >> 8);
6713 _val = AscReadLramWord(iop_base,
6714 (ushort)(q_addr +
6715 (ushort)ASC_SCSIQ_B_SENSE_LEN));
6716 scsiq->sense_len = (uchar)_val;
6717 scsiq->extra_bytes = (uchar)(_val >> 8);
6718
6719
6720
6721
6722 scsiq->remain_bytes = (((u32)AscReadLramWord(iop_base,
6723 (ushort)(q_addr +
6724 (ushort)
6725 ASC_SCSIQ_W_ALT_DC1)))
6726 << 16);
6727
6728
6729
6730 scsiq->remain_bytes += AscReadLramWord(iop_base,
6731 (ushort)(q_addr + (ushort)
6732 ASC_SCSIQ_DW_REMAIN_XFER_CNT));
6733
6734 scsiq->remain_bytes &= max_dma_count;
6735 return sg_queue_cnt;
6736}
6737
6738
6739
6740
6741
6742
6743static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
6744{
6745 struct asc_board *boardp = asc_dvc_varp->drv_ptr;
6746 u32 srb_tag;
6747 struct scsi_cmnd *scp;
6748
6749 ASC_DBG(1, "asc_dvc_varp 0x%p, qdonep 0x%p\n", asc_dvc_varp, qdonep);
6750 ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
6751
6752
6753
6754
6755 srb_tag = qdonep->d2.srb_tag - 1;
6756 scp = scsi_host_find_tag(boardp->shost, srb_tag);
6757 if (!scp)
6758 return;
6759
6760 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
6761
6762 ASC_STATS(boardp->shost, callback);
6763
6764 dma_unmap_single(boardp->dev, scp->SCp.dma_handle,
6765 SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
6766
6767
6768
6769 switch (qdonep->d3.done_stat) {
6770 case QD_NO_ERROR:
6771 ASC_DBG(2, "QD_NO_ERROR\n");
6772 scp->result = 0;
6773
6774
6775
6776
6777
6778
6779
6780 if (scsi_bufflen(scp) != 0 && qdonep->remain_bytes != 0 &&
6781 qdonep->remain_bytes <= scsi_bufflen(scp)) {
6782 ASC_DBG(1, "underrun condition %u bytes\n",
6783 (unsigned)qdonep->remain_bytes);
6784 scsi_set_resid(scp, qdonep->remain_bytes);
6785 }
6786 break;
6787
6788 case QD_WITH_ERROR:
6789 ASC_DBG(2, "QD_WITH_ERROR\n");
6790 switch (qdonep->d3.host_stat) {
6791 case QHSTA_NO_ERROR:
6792 if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
6793 ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n");
6794 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
6795 SCSI_SENSE_BUFFERSIZE);
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
6809 STATUS_BYTE(qdonep->d3.scsi_stat);
6810 } else {
6811 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
6812 }
6813 break;
6814
6815 default:
6816
6817 ASC_DBG(1, "host_stat 0x%x\n", qdonep->d3.host_stat);
6818 scp->result = HOST_BYTE(DID_BAD_TARGET);
6819 break;
6820 }
6821 break;
6822
6823 case QD_ABORTED_BY_HOST:
6824 ASC_DBG(1, "QD_ABORTED_BY_HOST\n");
6825 scp->result =
6826 HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.
6827 scsi_msg) |
6828 STATUS_BYTE(qdonep->d3.scsi_stat);
6829 break;
6830
6831 default:
6832 ASC_DBG(1, "done_stat 0x%x\n", qdonep->d3.done_stat);
6833 scp->result =
6834 HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.
6835 scsi_msg) |
6836 STATUS_BYTE(qdonep->d3.scsi_stat);
6837 break;
6838 }
6839
6840
6841
6842
6843
6844
6845 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
6846 qdonep->d3.done_stat == QD_NO_ERROR &&
6847 qdonep->d3.host_stat == QHSTA_NO_ERROR) {
6848 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
6849 }
6850
6851 asc_scsi_done(scp);
6852}
6853
6854static int AscIsrQDone(ASC_DVC_VAR *asc_dvc)
6855{
6856 uchar next_qp;
6857 uchar n_q_used;
6858 uchar sg_list_qp;
6859 uchar sg_queue_cnt;
6860 uchar q_cnt;
6861 uchar done_q_tail;
6862 uchar tid_no;
6863 ASC_SCSI_BIT_ID_TYPE scsi_busy;
6864 ASC_SCSI_BIT_ID_TYPE target_id;
6865 PortAddr iop_base;
6866 ushort q_addr;
6867 ushort sg_q_addr;
6868 uchar cur_target_qng;
6869 ASC_QDONE_INFO scsiq_buf;
6870 ASC_QDONE_INFO *scsiq;
6871 bool false_overrun;
6872
6873 iop_base = asc_dvc->iop_base;
6874 n_q_used = 1;
6875 scsiq = (ASC_QDONE_INFO *)&scsiq_buf;
6876 done_q_tail = (uchar)AscGetVarDoneQTail(iop_base);
6877 q_addr = ASC_QNO_TO_QADDR(done_q_tail);
6878 next_qp = AscReadLramByte(iop_base,
6879 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_FWD));
6880 if (next_qp != ASC_QLINK_END) {
6881 AscPutVarDoneQTail(iop_base, next_qp);
6882 q_addr = ASC_QNO_TO_QADDR(next_qp);
6883 sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
6884 asc_dvc->max_dma_count);
6885 AscWriteLramByte(iop_base,
6886 (ushort)(q_addr +
6887 (ushort)ASC_SCSIQ_B_STATUS),
6888 (uchar)(scsiq->
6889 q_status & (uchar)~(QS_READY |
6890 QS_ABORTED)));
6891 tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
6892 target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
6893 if ((scsiq->cntl & QC_SG_HEAD) != 0) {
6894 sg_q_addr = q_addr;
6895 sg_list_qp = next_qp;
6896 for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
6897 sg_list_qp = AscReadLramByte(iop_base,
6898 (ushort)(sg_q_addr
6899 + (ushort)
6900 ASC_SCSIQ_B_FWD));
6901 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
6902 if (sg_list_qp == ASC_QLINK_END) {
6903 AscSetLibErrorCode(asc_dvc,
6904 ASCQ_ERR_SG_Q_LINKS);
6905 scsiq->d3.done_stat = QD_WITH_ERROR;
6906 scsiq->d3.host_stat =
6907 QHSTA_D_QDONE_SG_LIST_CORRUPTED;
6908 goto FATAL_ERR_QDONE;
6909 }
6910 AscWriteLramByte(iop_base,
6911 (ushort)(sg_q_addr + (ushort)
6912 ASC_SCSIQ_B_STATUS),
6913 QS_FREE);
6914 }
6915 n_q_used = sg_queue_cnt + 1;
6916 AscPutVarDoneQTail(iop_base, sg_list_qp);
6917 }
6918 if (asc_dvc->queue_full_or_busy & target_id) {
6919 cur_target_qng = AscReadLramByte(iop_base,
6920 (ushort)((ushort)
6921 ASC_QADR_BEG
6922 + (ushort)
6923 scsiq->d2.
6924 target_ix));
6925 if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
6926 scsi_busy = AscReadLramByte(iop_base, (ushort)
6927 ASCV_SCSIBUSY_B);
6928 scsi_busy &= ~target_id;
6929 AscWriteLramByte(iop_base,
6930 (ushort)ASCV_SCSIBUSY_B,
6931 scsi_busy);
6932 asc_dvc->queue_full_or_busy &= ~target_id;
6933 }
6934 }
6935 if (asc_dvc->cur_total_qng >= n_q_used) {
6936 asc_dvc->cur_total_qng -= n_q_used;
6937 if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
6938 asc_dvc->cur_dvc_qng[tid_no]--;
6939 }
6940 } else {
6941 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
6942 scsiq->d3.done_stat = QD_WITH_ERROR;
6943 goto FATAL_ERR_QDONE;
6944 }
6945 if ((scsiq->d2.srb_tag == 0UL) ||
6946 ((scsiq->q_status & QS_ABORTED) != 0)) {
6947 return (0x11);
6948 } else if (scsiq->q_status == QS_DONE) {
6949
6950
6951
6952
6953 false_overrun = false;
6954 if (scsiq->extra_bytes != 0) {
6955 scsiq->remain_bytes += scsiq->extra_bytes;
6956 }
6957 if (scsiq->d3.done_stat == QD_WITH_ERROR) {
6958 if (scsiq->d3.host_stat ==
6959 QHSTA_M_DATA_OVER_RUN) {
6960 if ((scsiq->
6961 cntl & (QC_DATA_IN | QC_DATA_OUT))
6962 == 0) {
6963 scsiq->d3.done_stat =
6964 QD_NO_ERROR;
6965 scsiq->d3.host_stat =
6966 QHSTA_NO_ERROR;
6967 } else if (false_overrun) {
6968 scsiq->d3.done_stat =
6969 QD_NO_ERROR;
6970 scsiq->d3.host_stat =
6971 QHSTA_NO_ERROR;
6972 }
6973 } else if (scsiq->d3.host_stat ==
6974 QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
6975 AscStopChip(iop_base);
6976 AscSetChipControl(iop_base,
6977 (uchar)(CC_SCSI_RESET
6978 | CC_HALT));
6979 udelay(60);
6980 AscSetChipControl(iop_base, CC_HALT);
6981 AscSetChipStatus(iop_base,
6982 CIW_CLR_SCSI_RESET_INT);
6983 AscSetChipStatus(iop_base, 0);
6984 AscSetChipControl(iop_base, 0);
6985 }
6986 }
6987 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
6988 asc_isr_callback(asc_dvc, scsiq);
6989 } else {
6990 if ((AscReadLramByte(iop_base,
6991 (ushort)(q_addr + (ushort)
6992 ASC_SCSIQ_CDB_BEG))
6993 == START_STOP)) {
6994 asc_dvc->unit_not_ready &= ~target_id;
6995 if (scsiq->d3.done_stat != QD_NO_ERROR) {
6996 asc_dvc->start_motor &=
6997 ~target_id;
6998 }
6999 }
7000 }
7001 return (1);
7002 } else {
7003 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
7004 FATAL_ERR_QDONE:
7005 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
7006 asc_isr_callback(asc_dvc, scsiq);
7007 }
7008 return (0x80);
7009 }
7010 }
7011 return (0);
7012}
7013
7014static int AscISR(ASC_DVC_VAR *asc_dvc)
7015{
7016 ASC_CS_TYPE chipstat;
7017 PortAddr iop_base;
7018 ushort saved_ram_addr;
7019 uchar ctrl_reg;
7020 uchar saved_ctrl_reg;
7021 int int_pending;
7022 int status;
7023 uchar host_flag;
7024
7025 iop_base = asc_dvc->iop_base;
7026 int_pending = ASC_FALSE;
7027
7028 if (AscIsIntPending(iop_base) == 0)
7029 return int_pending;
7030
7031 if ((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0) {
7032 return ASC_ERROR;
7033 }
7034 if (asc_dvc->in_critical_cnt != 0) {
7035 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
7036 return ASC_ERROR;
7037 }
7038 if (asc_dvc->is_in_int) {
7039 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
7040 return ASC_ERROR;
7041 }
7042 asc_dvc->is_in_int = true;
7043 ctrl_reg = AscGetChipControl(iop_base);
7044 saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
7045 CC_SINGLE_STEP | CC_DIAG | CC_TEST));
7046 chipstat = AscGetChipStatus(iop_base);
7047 if (chipstat & CSW_SCSI_RESET_LATCH) {
7048 if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
7049 int i = 10;
7050 int_pending = ASC_TRUE;
7051 asc_dvc->sdtr_done = 0;
7052 saved_ctrl_reg &= (uchar)(~CC_HALT);
7053 while ((AscGetChipStatus(iop_base) &
7054 CSW_SCSI_RESET_ACTIVE) && (i-- > 0)) {
7055 mdelay(100);
7056 }
7057 AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
7058 AscSetChipControl(iop_base, CC_HALT);
7059 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
7060 AscSetChipStatus(iop_base, 0);
7061 chipstat = AscGetChipStatus(iop_base);
7062 }
7063 }
7064 saved_ram_addr = AscGetChipLramAddr(iop_base);
7065 host_flag = AscReadLramByte(iop_base,
7066 ASCV_HOST_FLAG_B) &
7067 (uchar)(~ASC_HOST_FLAG_IN_ISR);
7068 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
7069 (uchar)(host_flag | (uchar)ASC_HOST_FLAG_IN_ISR));
7070 if ((chipstat & CSW_INT_PENDING) || (int_pending)) {
7071 AscAckInterrupt(iop_base);
7072 int_pending = ASC_TRUE;
7073 if ((chipstat & CSW_HALTED) && (ctrl_reg & CC_SINGLE_STEP)) {
7074 AscIsrChipHalted(asc_dvc);
7075 saved_ctrl_reg &= (uchar)(~CC_HALT);
7076 } else {
7077 if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
7078 while (((status =
7079 AscIsrQDone(asc_dvc)) & 0x01) != 0) {
7080 }
7081 } else {
7082 do {
7083 if ((status =
7084 AscIsrQDone(asc_dvc)) == 1) {
7085 break;
7086 }
7087 } while (status == 0x11);
7088 }
7089 if ((status & 0x80) != 0)
7090 int_pending = ASC_ERROR;
7091 }
7092 }
7093 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
7094 AscSetChipLramAddr(iop_base, saved_ram_addr);
7095 AscSetChipControl(iop_base, saved_ctrl_reg);
7096 asc_dvc->is_in_int = false;
7097 return int_pending;
7098}
7099
7100
7101
7102
7103
7104
7105
7106
7107
7108
7109static int advansys_reset(struct scsi_cmnd *scp)
7110{
7111 struct Scsi_Host *shost = scp->device->host;
7112 struct asc_board *boardp = shost_priv(shost);
7113 unsigned long flags;
7114 int status;
7115 int ret = SUCCESS;
7116
7117 ASC_DBG(1, "0x%p\n", scp);
7118
7119 ASC_STATS(shost, reset);
7120
7121 scmd_printk(KERN_INFO, scp, "SCSI host reset started...\n");
7122
7123 if (ASC_NARROW_BOARD(boardp)) {
7124 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
7125
7126
7127 ASC_DBG(1, "before AscInitAsc1000Driver()\n");
7128 status = AscInitAsc1000Driver(asc_dvc);
7129
7130
7131 if (asc_dvc->err_code || !asc_dvc->overrun_dma) {
7132 scmd_printk(KERN_INFO, scp, "SCSI host reset error: "
7133 "0x%x, status: 0x%x\n", asc_dvc->err_code,
7134 status);
7135 ret = FAILED;
7136 } else if (status) {
7137 scmd_printk(KERN_INFO, scp, "SCSI host reset warning: "
7138 "0x%x\n", status);
7139 } else {
7140 scmd_printk(KERN_INFO, scp, "SCSI host reset "
7141 "successful\n");
7142 }
7143
7144 ASC_DBG(1, "after AscInitAsc1000Driver()\n");
7145 } else {
7146
7147
7148
7149
7150 ADV_DVC_VAR *adv_dvc = &boardp->dvc_var.adv_dvc_var;
7151
7152
7153
7154
7155 ASC_DBG(1, "before AdvResetChipAndSB()\n");
7156 switch (AdvResetChipAndSB(adv_dvc)) {
7157 case ASC_TRUE:
7158 scmd_printk(KERN_INFO, scp, "SCSI host reset "
7159 "successful\n");
7160 break;
7161 case ASC_FALSE:
7162 default:
7163 scmd_printk(KERN_INFO, scp, "SCSI host reset error\n");
7164 ret = FAILED;
7165 break;
7166 }
7167 spin_lock_irqsave(shost->host_lock, flags);
7168 AdvISR(adv_dvc);
7169 spin_unlock_irqrestore(shost->host_lock, flags);
7170 }
7171
7172 ASC_DBG(1, "ret %d\n", ret);
7173
7174 return ret;
7175}
7176
7177
7178
7179
7180
7181
7182
7183
7184
7185
7186
7187
7188static int
7189advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
7190 sector_t capacity, int ip[])
7191{
7192 struct asc_board *boardp = shost_priv(sdev->host);
7193
7194 ASC_DBG(1, "begin\n");
7195 ASC_STATS(sdev->host, biosparam);
7196 if (ASC_NARROW_BOARD(boardp)) {
7197 if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
7198 ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) {
7199 ip[0] = 255;
7200 ip[1] = 63;
7201 } else {
7202 ip[0] = 64;
7203 ip[1] = 32;
7204 }
7205 } else {
7206 if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
7207 BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) {
7208 ip[0] = 255;
7209 ip[1] = 63;
7210 } else {
7211 ip[0] = 64;
7212 ip[1] = 32;
7213 }
7214 }
7215 ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
7216 ASC_DBG(1, "end\n");
7217 return 0;
7218}
7219
7220
7221
7222
7223
7224
7225static irqreturn_t advansys_interrupt(int irq, void *dev_id)
7226{
7227 struct Scsi_Host *shost = dev_id;
7228 struct asc_board *boardp = shost_priv(shost);
7229 irqreturn_t result = IRQ_NONE;
7230 unsigned long flags;
7231
7232 ASC_DBG(2, "boardp 0x%p\n", boardp);
7233 spin_lock_irqsave(shost->host_lock, flags);
7234 if (ASC_NARROW_BOARD(boardp)) {
7235 if (AscIsIntPending(shost->io_port)) {
7236 result = IRQ_HANDLED;
7237 ASC_STATS(shost, interrupt);
7238 ASC_DBG(1, "before AscISR()\n");
7239 AscISR(&boardp->dvc_var.asc_dvc_var);
7240 }
7241 } else {
7242 ASC_DBG(1, "before AdvISR()\n");
7243 if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
7244 result = IRQ_HANDLED;
7245 ASC_STATS(shost, interrupt);
7246 }
7247 }
7248 spin_unlock_irqrestore(shost->host_lock, flags);
7249
7250 ASC_DBG(1, "end\n");
7251 return result;
7252}
7253
7254static bool AscHostReqRiscHalt(PortAddr iop_base)
7255{
7256 int count = 0;
7257 bool sta = false;
7258 uchar saved_stop_code;
7259
7260 if (AscIsChipHalted(iop_base))
7261 return true;
7262 saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
7263 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
7264 ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP);
7265 do {
7266 if (AscIsChipHalted(iop_base)) {
7267 sta = true;
7268 break;
7269 }
7270 mdelay(100);
7271 } while (count++ < 20);
7272 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
7273 return sta;
7274}
7275
7276static bool
7277AscSetRunChipSynRegAtID(PortAddr iop_base, uchar tid_no, uchar sdtr_data)
7278{
7279 bool sta = false;
7280
7281 if (AscHostReqRiscHalt(iop_base)) {
7282 sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
7283 AscStartChip(iop_base);
7284 }
7285 return sta;
7286}
7287
7288static void AscAsyncFix(ASC_DVC_VAR *asc_dvc, struct scsi_device *sdev)
7289{
7290 char type = sdev->type;
7291 ASC_SCSI_BIT_ID_TYPE tid_bits = 1 << sdev->id;
7292
7293 if (!(asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN))
7294 return;
7295 if (asc_dvc->init_sdtr & tid_bits)
7296 return;
7297
7298 if ((type == TYPE_ROM) && (strncmp(sdev->vendor, "HP ", 3) == 0))
7299 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
7300
7301 asc_dvc->pci_fix_asyn_xfer |= tid_bits;
7302 if ((type == TYPE_PROCESSOR) || (type == TYPE_SCANNER) ||
7303 (type == TYPE_ROM) || (type == TYPE_TAPE))
7304 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
7305
7306 if (asc_dvc->pci_fix_asyn_xfer & tid_bits)
7307 AscSetRunChipSynRegAtID(asc_dvc->iop_base, sdev->id,
7308 ASYN_SDTR_DATA_FIX_PCI_REV_AB);
7309}
7310
7311static void
7312advansys_narrow_slave_configure(struct scsi_device *sdev, ASC_DVC_VAR *asc_dvc)
7313{
7314 ASC_SCSI_BIT_ID_TYPE tid_bit = 1 << sdev->id;
7315 ASC_SCSI_BIT_ID_TYPE orig_use_tagged_qng = asc_dvc->use_tagged_qng;
7316
7317 if (sdev->lun == 0) {
7318 ASC_SCSI_BIT_ID_TYPE orig_init_sdtr = asc_dvc->init_sdtr;
7319 if ((asc_dvc->cfg->sdtr_enable & tid_bit) && sdev->sdtr) {
7320 asc_dvc->init_sdtr |= tid_bit;
7321 } else {
7322 asc_dvc->init_sdtr &= ~tid_bit;
7323 }
7324
7325 if (orig_init_sdtr != asc_dvc->init_sdtr)
7326 AscAsyncFix(asc_dvc, sdev);
7327 }
7328
7329 if (sdev->tagged_supported) {
7330 if (asc_dvc->cfg->cmd_qng_enabled & tid_bit) {
7331 if (sdev->lun == 0) {
7332 asc_dvc->cfg->can_tagged_qng |= tid_bit;
7333 asc_dvc->use_tagged_qng |= tid_bit;
7334 }
7335 scsi_change_queue_depth(sdev,
7336 asc_dvc->max_dvc_qng[sdev->id]);
7337 }
7338 } else {
7339 if (sdev->lun == 0) {
7340 asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
7341 asc_dvc->use_tagged_qng &= ~tid_bit;
7342 }
7343 }
7344
7345 if ((sdev->lun == 0) &&
7346 (orig_use_tagged_qng != asc_dvc->use_tagged_qng)) {
7347 AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
7348 asc_dvc->cfg->disc_enable);
7349 AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
7350 asc_dvc->use_tagged_qng);
7351 AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
7352 asc_dvc->cfg->can_tagged_qng);
7353
7354 asc_dvc->max_dvc_qng[sdev->id] =
7355 asc_dvc->cfg->max_tag_qng[sdev->id];
7356 AscWriteLramByte(asc_dvc->iop_base,
7357 (ushort)(ASCV_MAX_DVC_QNG_BEG + sdev->id),
7358 asc_dvc->max_dvc_qng[sdev->id]);
7359 }
7360}
7361
7362
7363
7364
7365
7366
7367
7368
7369static void
7370advansys_wide_enable_wdtr(AdvPortAddr iop_base, unsigned short tidmask)
7371{
7372 unsigned short cfg_word;
7373 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
7374 if ((cfg_word & tidmask) != 0)
7375 return;
7376
7377 cfg_word |= tidmask;
7378 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
7379
7380
7381
7382
7383
7384
7385
7386 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
7387 cfg_word &= ~tidmask;
7388 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
7389 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
7390 cfg_word &= ~tidmask;
7391 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
7392}
7393
7394
7395
7396
7397
7398
7399
7400
7401static void
7402advansys_wide_enable_sdtr(AdvPortAddr iop_base, unsigned short tidmask)
7403{
7404 unsigned short cfg_word;
7405 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
7406 if ((cfg_word & tidmask) != 0)
7407 return;
7408
7409 cfg_word |= tidmask;
7410 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
7411
7412
7413
7414
7415
7416 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
7417 cfg_word &= ~tidmask;
7418 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
7419}
7420
7421
7422
7423
7424
7425
7426
7427
7428
7429static void advansys_wide_enable_ppr(ADV_DVC_VAR *adv_dvc,
7430 AdvPortAddr iop_base, unsigned short tidmask)
7431{
7432 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
7433 adv_dvc->ppr_able |= tidmask;
7434 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
7435}
7436
7437static void
7438advansys_wide_slave_configure(struct scsi_device *sdev, ADV_DVC_VAR *adv_dvc)
7439{
7440 AdvPortAddr iop_base = adv_dvc->iop_base;
7441 unsigned short tidmask = 1 << sdev->id;
7442
7443 if (sdev->lun == 0) {
7444
7445
7446
7447
7448
7449
7450 if ((adv_dvc->wdtr_able & tidmask) && sdev->wdtr)
7451 advansys_wide_enable_wdtr(iop_base, tidmask);
7452 if ((adv_dvc->sdtr_able & tidmask) && sdev->sdtr)
7453 advansys_wide_enable_sdtr(iop_base, tidmask);
7454 if (adv_dvc->chip_type == ADV_CHIP_ASC38C1600 && sdev->ppr)
7455 advansys_wide_enable_ppr(adv_dvc, iop_base, tidmask);
7456
7457
7458
7459
7460
7461
7462
7463 if ((adv_dvc->tagqng_able & tidmask) &&
7464 sdev->tagged_supported) {
7465 unsigned short cfg_word;
7466 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
7467 cfg_word |= tidmask;
7468 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
7469 cfg_word);
7470 AdvWriteByteLram(iop_base,
7471 ASC_MC_NUMBER_OF_MAX_CMD + sdev->id,
7472 adv_dvc->max_dvc_qng);
7473 }
7474 }
7475
7476 if ((adv_dvc->tagqng_able & tidmask) && sdev->tagged_supported)
7477 scsi_change_queue_depth(sdev, adv_dvc->max_dvc_qng);
7478}
7479
7480
7481
7482
7483
7484static int advansys_slave_configure(struct scsi_device *sdev)
7485{
7486 struct asc_board *boardp = shost_priv(sdev->host);
7487
7488 if (ASC_NARROW_BOARD(boardp))
7489 advansys_narrow_slave_configure(sdev,
7490 &boardp->dvc_var.asc_dvc_var);
7491 else
7492 advansys_wide_slave_configure(sdev,
7493 &boardp->dvc_var.adv_dvc_var);
7494
7495 return 0;
7496}
7497
7498static __le32 asc_get_sense_buffer_dma(struct scsi_cmnd *scp)
7499{
7500 struct asc_board *board = shost_priv(scp->device->host);
7501
7502 scp->SCp.dma_handle = dma_map_single(board->dev, scp->sense_buffer,
7503 SCSI_SENSE_BUFFERSIZE,
7504 DMA_FROM_DEVICE);
7505 if (dma_mapping_error(board->dev, scp->SCp.dma_handle)) {
7506 ASC_DBG(1, "failed to map sense buffer\n");
7507 return 0;
7508 }
7509 return cpu_to_le32(scp->SCp.dma_handle);
7510}
7511
7512static int asc_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,
7513 struct asc_scsi_q *asc_scsi_q)
7514{
7515 struct asc_dvc_var *asc_dvc = &boardp->dvc_var.asc_dvc_var;
7516 int use_sg;
7517 u32 srb_tag;
7518
7519 memset(asc_scsi_q, 0, sizeof(*asc_scsi_q));
7520
7521
7522
7523
7524
7525 srb_tag = scp->request->tag + 1;
7526 asc_scsi_q->q2.srb_tag = srb_tag;
7527
7528
7529
7530
7531 asc_scsi_q->cdbptr = &scp->cmnd[0];
7532 asc_scsi_q->q2.cdb_len = scp->cmd_len;
7533 asc_scsi_q->q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
7534 asc_scsi_q->q1.target_lun = scp->device->lun;
7535 asc_scsi_q->q2.target_ix =
7536 ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
7537 asc_scsi_q->q1.sense_addr = asc_get_sense_buffer_dma(scp);
7538 asc_scsi_q->q1.sense_len = SCSI_SENSE_BUFFERSIZE;
7539 if (!asc_scsi_q->q1.sense_addr)
7540 return ASC_BUSY;
7541
7542
7543
7544
7545
7546
7547
7548
7549
7550
7551
7552
7553 if ((asc_dvc->cur_dvc_qng[scp->device->id] > 0) &&
7554 (boardp->reqcnt[scp->device->id] % 255) == 0) {
7555 asc_scsi_q->q2.tag_code = ORDERED_QUEUE_TAG;
7556 } else {
7557 asc_scsi_q->q2.tag_code = SIMPLE_QUEUE_TAG;
7558 }
7559
7560
7561 use_sg = scsi_dma_map(scp);
7562 if (use_sg < 0) {
7563 ASC_DBG(1, "failed to map sglist\n");
7564 return ASC_BUSY;
7565 } else if (use_sg > 0) {
7566 int sgcnt;
7567 struct scatterlist *slp;
7568 struct asc_sg_head *asc_sg_head;
7569
7570 if (use_sg > scp->device->host->sg_tablesize) {
7571 scmd_printk(KERN_ERR, scp, "use_sg %d > "
7572 "sg_tablesize %d\n", use_sg,
7573 scp->device->host->sg_tablesize);
7574 scsi_dma_unmap(scp);
7575 scp->result = HOST_BYTE(DID_ERROR);
7576 return ASC_ERROR;
7577 }
7578
7579 asc_sg_head = kzalloc(sizeof(asc_scsi_q->sg_head) +
7580 use_sg * sizeof(struct asc_sg_list), GFP_ATOMIC);
7581 if (!asc_sg_head) {
7582 scsi_dma_unmap(scp);
7583 scp->result = HOST_BYTE(DID_SOFT_ERROR);
7584 return ASC_ERROR;
7585 }
7586
7587 asc_scsi_q->q1.cntl |= QC_SG_HEAD;
7588 asc_scsi_q->sg_head = asc_sg_head;
7589 asc_scsi_q->q1.data_cnt = 0;
7590 asc_scsi_q->q1.data_addr = 0;
7591
7592 asc_sg_head->entry_cnt = asc_scsi_q->q1.sg_queue_cnt = use_sg;
7593 ASC_STATS_ADD(scp->device->host, xfer_elem,
7594 asc_sg_head->entry_cnt);
7595
7596
7597
7598
7599 scsi_for_each_sg(scp, slp, use_sg, sgcnt) {
7600 asc_sg_head->sg_list[sgcnt].addr =
7601 cpu_to_le32(sg_dma_address(slp));
7602 asc_sg_head->sg_list[sgcnt].bytes =
7603 cpu_to_le32(sg_dma_len(slp));
7604 ASC_STATS_ADD(scp->device->host, xfer_sect,
7605 DIV_ROUND_UP(sg_dma_len(slp), 512));
7606 }
7607 }
7608
7609 ASC_STATS(scp->device->host, xfer_cnt);
7610
7611 ASC_DBG_PRT_ASC_SCSI_Q(2, asc_scsi_q);
7612 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
7613
7614 return ASC_NOERROR;
7615}
7616
7617
7618
7619
7620
7621
7622
7623
7624
7625
7626
7627
7628
7629static int
7630adv_get_sglist(struct asc_board *boardp, adv_req_t *reqp,
7631 ADV_SCSI_REQ_Q *scsiqp, struct scsi_cmnd *scp, int use_sg)
7632{
7633 adv_sgblk_t *sgblkp, *prev_sgblkp;
7634 struct scatterlist *slp;
7635 int sg_elem_cnt;
7636 ADV_SG_BLOCK *sg_block, *prev_sg_block;
7637 dma_addr_t sgblk_paddr;
7638 int i;
7639
7640 slp = scsi_sglist(scp);
7641 sg_elem_cnt = use_sg;
7642 prev_sgblkp = NULL;
7643 prev_sg_block = NULL;
7644 reqp->sgblkp = NULL;
7645
7646 for (;;) {
7647
7648
7649
7650
7651
7652 sgblkp = dma_pool_alloc(boardp->adv_sgblk_pool, GFP_ATOMIC,
7653 &sgblk_paddr);
7654 if (!sgblkp) {
7655 ASC_DBG(1, "no free adv_sgblk_t\n");
7656 ASC_STATS(scp->device->host, adv_build_nosg);
7657
7658
7659
7660
7661
7662 while ((sgblkp = reqp->sgblkp) != NULL) {
7663
7664 reqp->sgblkp = sgblkp->next_sgblkp;
7665 sgblkp->next_sgblkp = NULL;
7666 dma_pool_free(boardp->adv_sgblk_pool, sgblkp,
7667 sgblkp->sg_addr);
7668 }
7669 return ASC_BUSY;
7670 }
7671
7672 sgblkp->sg_addr = sgblk_paddr;
7673 sgblkp->next_sgblkp = NULL;
7674 sg_block = &sgblkp->sg_block;
7675
7676
7677
7678
7679
7680 if (reqp->sgblkp == NULL) {
7681
7682 reqp->sgblkp = sgblkp;
7683
7684
7685
7686
7687
7688 scsiqp->sg_list_ptr = sg_block;
7689 scsiqp->sg_real_addr = cpu_to_le32(sgblk_paddr);
7690 } else {
7691
7692 prev_sgblkp->next_sgblkp = sgblkp;
7693
7694
7695
7696
7697
7698 prev_sg_block->sg_ptr = cpu_to_le32(sgblk_paddr);
7699 }
7700
7701 for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) {
7702 sg_block->sg_list[i].sg_addr =
7703 cpu_to_le32(sg_dma_address(slp));
7704 sg_block->sg_list[i].sg_count =
7705 cpu_to_le32(sg_dma_len(slp));
7706 ASC_STATS_ADD(scp->device->host, xfer_sect,
7707 DIV_ROUND_UP(sg_dma_len(slp), 512));
7708
7709 if (--sg_elem_cnt == 0) {
7710
7711
7712
7713 sg_block->sg_cnt = i + 1;
7714 sg_block->sg_ptr = 0L;
7715 return ADV_SUCCESS;
7716 }
7717 slp++;
7718 }
7719 sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
7720 prev_sg_block = sg_block;
7721 prev_sgblkp = sgblkp;
7722 }
7723}
7724
7725
7726
7727
7728
7729
7730
7731
7732
7733
7734
7735static int
7736adv_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,
7737 adv_req_t **adv_reqpp)
7738{
7739 u32 srb_tag = scp->request->tag;
7740 adv_req_t *reqp;
7741 ADV_SCSI_REQ_Q *scsiqp;
7742 int ret;
7743 int use_sg;
7744 dma_addr_t sense_addr;
7745
7746
7747
7748
7749
7750 reqp = &boardp->adv_reqp[srb_tag];
7751 if (reqp->cmndp && reqp->cmndp != scp ) {
7752 ASC_DBG(1, "no free adv_req_t\n");
7753 ASC_STATS(scp->device->host, adv_build_noreq);
7754 return ASC_BUSY;
7755 }
7756
7757 reqp->req_addr = boardp->adv_reqp_addr + (srb_tag * sizeof(adv_req_t));
7758
7759 scsiqp = &reqp->scsi_req_q;
7760
7761
7762
7763
7764 scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
7765
7766
7767
7768
7769 scsiqp->srb_tag = srb_tag;
7770
7771
7772
7773
7774 reqp->cmndp = scp;
7775 scp->host_scribble = (void *)reqp;
7776
7777
7778
7779
7780
7781
7782 scsiqp->cdb_len = scp->cmd_len;
7783
7784 memcpy(scsiqp->cdb, scp->cmnd, scp->cmd_len < 12 ? scp->cmd_len : 12);
7785
7786 if (scp->cmd_len > 12) {
7787 int cdb16_len = scp->cmd_len - 12;
7788
7789 memcpy(scsiqp->cdb16, &scp->cmnd[12], cdb16_len);
7790 }
7791
7792 scsiqp->target_id = scp->device->id;
7793 scsiqp->target_lun = scp->device->lun;
7794
7795 sense_addr = dma_map_single(boardp->dev, scp->sense_buffer,
7796 SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
7797 if (dma_mapping_error(boardp->dev, sense_addr)) {
7798 ASC_DBG(1, "failed to map sense buffer\n");
7799 ASC_STATS(scp->device->host, adv_build_noreq);
7800 return ASC_BUSY;
7801 }
7802 scsiqp->sense_addr = cpu_to_le32(sense_addr);
7803 scsiqp->sense_len = SCSI_SENSE_BUFFERSIZE;
7804
7805
7806
7807 use_sg = scsi_dma_map(scp);
7808 if (use_sg < 0) {
7809 ASC_DBG(1, "failed to map SG list\n");
7810 ASC_STATS(scp->device->host, adv_build_noreq);
7811 return ASC_BUSY;
7812 } else if (use_sg == 0) {
7813
7814 reqp->sgblkp = NULL;
7815 scsiqp->data_cnt = 0;
7816
7817 scsiqp->data_addr = 0;
7818 scsiqp->sg_list_ptr = NULL;
7819 scsiqp->sg_real_addr = 0;
7820 } else {
7821 if (use_sg > ADV_MAX_SG_LIST) {
7822 scmd_printk(KERN_ERR, scp, "use_sg %d > "
7823 "ADV_MAX_SG_LIST %d\n", use_sg,
7824 scp->device->host->sg_tablesize);
7825 scsi_dma_unmap(scp);
7826 scp->result = HOST_BYTE(DID_ERROR);
7827 reqp->cmndp = NULL;
7828 scp->host_scribble = NULL;
7829
7830 return ASC_ERROR;
7831 }
7832
7833 scsiqp->data_cnt = cpu_to_le32(scsi_bufflen(scp));
7834
7835 ret = adv_get_sglist(boardp, reqp, scsiqp, scp, use_sg);
7836 if (ret != ADV_SUCCESS) {
7837 scsi_dma_unmap(scp);
7838 scp->result = HOST_BYTE(DID_ERROR);
7839 reqp->cmndp = NULL;
7840 scp->host_scribble = NULL;
7841
7842 return ret;
7843 }
7844
7845 ASC_STATS_ADD(scp->device->host, xfer_elem, use_sg);
7846 }
7847
7848 ASC_STATS(scp->device->host, xfer_cnt);
7849
7850 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
7851 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
7852
7853 *adv_reqpp = reqp;
7854
7855 return ASC_NOERROR;
7856}
7857
7858static int AscSgListToQueue(int sg_list)
7859{
7860 int n_sg_list_qs;
7861
7862 n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
7863 if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
7864 n_sg_list_qs++;
7865 return n_sg_list_qs + 1;
7866}
7867
7868static uint
7869AscGetNumOfFreeQueue(ASC_DVC_VAR *asc_dvc, uchar target_ix, uchar n_qs)
7870{
7871 uint cur_used_qs;
7872 uint cur_free_qs;
7873 ASC_SCSI_BIT_ID_TYPE target_id;
7874 uchar tid_no;
7875
7876 target_id = ASC_TIX_TO_TARGET_ID(target_ix);
7877 tid_no = ASC_TIX_TO_TID(target_ix);
7878 if ((asc_dvc->unit_not_ready & target_id) ||
7879 (asc_dvc->queue_full_or_busy & target_id)) {
7880 return 0;
7881 }
7882 if (n_qs == 1) {
7883 cur_used_qs = (uint) asc_dvc->cur_total_qng +
7884 (uint) asc_dvc->last_q_shortage + (uint) ASC_MIN_FREE_Q;
7885 } else {
7886 cur_used_qs = (uint) asc_dvc->cur_total_qng +
7887 (uint) ASC_MIN_FREE_Q;
7888 }
7889 if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
7890 cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
7891 if (asc_dvc->cur_dvc_qng[tid_no] >=
7892 asc_dvc->max_dvc_qng[tid_no]) {
7893 return 0;
7894 }
7895 return cur_free_qs;
7896 }
7897 if (n_qs > 1) {
7898 if ((n_qs > asc_dvc->last_q_shortage)
7899 && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
7900 asc_dvc->last_q_shortage = n_qs;
7901 }
7902 }
7903 return 0;
7904}
7905
7906static uchar AscAllocFreeQueue(PortAddr iop_base, uchar free_q_head)
7907{
7908 ushort q_addr;
7909 uchar next_qp;
7910 uchar q_status;
7911
7912 q_addr = ASC_QNO_TO_QADDR(free_q_head);
7913 q_status = (uchar)AscReadLramByte(iop_base,
7914 (ushort)(q_addr +
7915 ASC_SCSIQ_B_STATUS));
7916 next_qp = AscReadLramByte(iop_base, (ushort)(q_addr + ASC_SCSIQ_B_FWD));
7917 if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END))
7918 return next_qp;
7919 return ASC_QLINK_END;
7920}
7921
7922static uchar
7923AscAllocMultipleFreeQueue(PortAddr iop_base, uchar free_q_head, uchar n_free_q)
7924{
7925 uchar i;
7926
7927 for (i = 0; i < n_free_q; i++) {
7928 free_q_head = AscAllocFreeQueue(iop_base, free_q_head);
7929 if (free_q_head == ASC_QLINK_END)
7930 break;
7931 }
7932 return free_q_head;
7933}
7934
7935
7936
7937
7938
7939
7940
7941
7942
7943
7944
7945static void
7946DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
7947{
7948 int i;
7949
7950 ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
7951 AscSetChipLramAddr(iop_base, s_addr);
7952 for (i = 0; i < 2 * words; i += 2) {
7953 if (i == 4 || i == 20) {
7954 continue;
7955 }
7956 outpw(iop_base + IOP_RAM_DATA,
7957 ((ushort)outbuf[i + 1] << 8) | outbuf[i]);
7958 }
7959}
7960
7961static int AscPutReadyQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
7962{
7963 ushort q_addr;
7964 uchar tid_no;
7965 uchar sdtr_data;
7966 uchar syn_period_ix;
7967 uchar syn_offset;
7968 PortAddr iop_base;
7969
7970 iop_base = asc_dvc->iop_base;
7971 if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
7972 ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
7973 tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
7974 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
7975 syn_period_ix =
7976 (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
7977 syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
7978 AscMsgOutSDTR(asc_dvc,
7979 asc_dvc->sdtr_period_tbl[syn_period_ix],
7980 syn_offset);
7981 scsiq->q1.cntl |= QC_MSG_OUT;
7982 }
7983 q_addr = ASC_QNO_TO_QADDR(q_no);
7984 if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
7985 scsiq->q2.tag_code &= ~SIMPLE_QUEUE_TAG;
7986 }
7987 scsiq->q1.status = QS_FREE;
7988 AscMemWordCopyPtrToLram(iop_base,
7989 q_addr + ASC_SCSIQ_CDB_BEG,
7990 (uchar *)scsiq->cdbptr, scsiq->q2.cdb_len >> 1);
7991
7992 DvcPutScsiQ(iop_base,
7993 q_addr + ASC_SCSIQ_CPY_BEG,
7994 (uchar *)&scsiq->q1.cntl,
7995 ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
7996 AscWriteLramWord(iop_base,
7997 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS),
7998 (ushort)(((ushort)scsiq->q1.
7999 q_no << 8) | (ushort)QS_READY));
8000 return 1;
8001}
8002
8003static int
8004AscPutReadySgListQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
8005{
8006 int sta;
8007 int i;
8008 ASC_SG_HEAD *sg_head;
8009 ASC_SG_LIST_Q scsi_sg_q;
8010 __le32 saved_data_addr;
8011 __le32 saved_data_cnt;
8012 PortAddr iop_base;
8013 ushort sg_list_dwords;
8014 ushort sg_index;
8015 ushort sg_entry_cnt;
8016 ushort q_addr;
8017 uchar next_qp;
8018
8019 iop_base = asc_dvc->iop_base;
8020 sg_head = scsiq->sg_head;
8021 saved_data_addr = scsiq->q1.data_addr;
8022 saved_data_cnt = scsiq->q1.data_cnt;
8023 scsiq->q1.data_addr = cpu_to_le32(sg_head->sg_list[0].addr);
8024 scsiq->q1.data_cnt = cpu_to_le32(sg_head->sg_list[0].bytes);
8025
8026
8027
8028
8029
8030 sg_entry_cnt = sg_head->entry_cnt - 1;
8031
8032 if (sg_entry_cnt != 0) {
8033 scsiq->q1.cntl |= QC_SG_HEAD;
8034 q_addr = ASC_QNO_TO_QADDR(q_no);
8035 sg_index = 1;
8036 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
8037 scsi_sg_q.sg_head_qp = q_no;
8038 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
8039 for (i = 0; i < sg_head->queue_cnt; i++) {
8040 scsi_sg_q.seq_no = i + 1;
8041 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
8042 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
8043 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
8044 if (i == 0) {
8045 scsi_sg_q.sg_list_cnt =
8046 ASC_SG_LIST_PER_Q;
8047 scsi_sg_q.sg_cur_list_cnt =
8048 ASC_SG_LIST_PER_Q;
8049 } else {
8050 scsi_sg_q.sg_list_cnt =
8051 ASC_SG_LIST_PER_Q - 1;
8052 scsi_sg_q.sg_cur_list_cnt =
8053 ASC_SG_LIST_PER_Q - 1;
8054 }
8055 } else {
8056 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
8057 sg_list_dwords = sg_entry_cnt << 1;
8058 if (i == 0) {
8059 scsi_sg_q.sg_list_cnt = sg_entry_cnt;
8060 scsi_sg_q.sg_cur_list_cnt =
8061 sg_entry_cnt;
8062 } else {
8063 scsi_sg_q.sg_list_cnt =
8064 sg_entry_cnt - 1;
8065 scsi_sg_q.sg_cur_list_cnt =
8066 sg_entry_cnt - 1;
8067 }
8068 sg_entry_cnt = 0;
8069 }
8070 next_qp = AscReadLramByte(iop_base,
8071 (ushort)(q_addr +
8072 ASC_SCSIQ_B_FWD));
8073 scsi_sg_q.q_no = next_qp;
8074 q_addr = ASC_QNO_TO_QADDR(next_qp);
8075 AscMemWordCopyPtrToLram(iop_base,
8076 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
8077 (uchar *)&scsi_sg_q,
8078 sizeof(ASC_SG_LIST_Q) >> 1);
8079 AscMemDWordCopyPtrToLram(iop_base,
8080 q_addr + ASC_SGQ_LIST_BEG,
8081 (uchar *)&sg_head->
8082 sg_list[sg_index],
8083 sg_list_dwords);
8084 sg_index += ASC_SG_LIST_PER_Q;
8085 scsiq->next_sg_index = sg_index;
8086 }
8087 } else {
8088 scsiq->q1.cntl &= ~QC_SG_HEAD;
8089 }
8090 sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
8091 scsiq->q1.data_addr = saved_data_addr;
8092 scsiq->q1.data_cnt = saved_data_cnt;
8093 return (sta);
8094}
8095
8096static int
8097AscSendScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar n_q_required)
8098{
8099 PortAddr iop_base;
8100 uchar free_q_head;
8101 uchar next_qp;
8102 uchar tid_no;
8103 uchar target_ix;
8104 int sta;
8105
8106 iop_base = asc_dvc->iop_base;
8107 target_ix = scsiq->q2.target_ix;
8108 tid_no = ASC_TIX_TO_TID(target_ix);
8109 sta = 0;
8110 free_q_head = (uchar)AscGetVarFreeQHead(iop_base);
8111 if (n_q_required > 1) {
8112 next_qp = AscAllocMultipleFreeQueue(iop_base, free_q_head,
8113 (uchar)n_q_required);
8114 if (next_qp != ASC_QLINK_END) {
8115 asc_dvc->last_q_shortage = 0;
8116 scsiq->sg_head->queue_cnt = n_q_required - 1;
8117 scsiq->q1.q_no = free_q_head;
8118 sta = AscPutReadySgListQueue(asc_dvc, scsiq,
8119 free_q_head);
8120 }
8121 } else if (n_q_required == 1) {
8122 next_qp = AscAllocFreeQueue(iop_base, free_q_head);
8123 if (next_qp != ASC_QLINK_END) {
8124 scsiq->q1.q_no = free_q_head;
8125 sta = AscPutReadyQueue(asc_dvc, scsiq, free_q_head);
8126 }
8127 }
8128 if (sta == 1) {
8129 AscPutVarFreeQHead(iop_base, next_qp);
8130 asc_dvc->cur_total_qng += n_q_required;
8131 asc_dvc->cur_dvc_qng[tid_no]++;
8132 }
8133 return sta;
8134}
8135
8136#define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16
8137static uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = {
8138 INQUIRY,
8139 REQUEST_SENSE,
8140 READ_CAPACITY,
8141 READ_TOC,
8142 MODE_SELECT,
8143 MODE_SENSE,
8144 MODE_SELECT_10,
8145 MODE_SENSE_10,
8146 0xFF,
8147 0xFF,
8148 0xFF,
8149 0xFF,
8150 0xFF,
8151 0xFF,
8152 0xFF,
8153 0xFF
8154};
8155
8156static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq)
8157{
8158 PortAddr iop_base;
8159 int sta;
8160 int n_q_required;
8161 bool disable_syn_offset_one_fix;
8162 int i;
8163 u32 addr;
8164 ushort sg_entry_cnt = 0;
8165 ushort sg_entry_cnt_minus_one = 0;
8166 uchar target_ix;
8167 uchar tid_no;
8168 uchar sdtr_data;
8169 uchar extra_bytes;
8170 uchar scsi_cmd;
8171 uchar disable_cmd;
8172 ASC_SG_HEAD *sg_head;
8173 unsigned long data_cnt;
8174
8175 iop_base = asc_dvc->iop_base;
8176 sg_head = scsiq->sg_head;
8177 if (asc_dvc->err_code != 0)
8178 return ASC_ERROR;
8179 scsiq->q1.q_no = 0;
8180 if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
8181 scsiq->q1.extra_bytes = 0;
8182 }
8183 sta = 0;
8184 target_ix = scsiq->q2.target_ix;
8185 tid_no = ASC_TIX_TO_TID(target_ix);
8186 n_q_required = 1;
8187 if (scsiq->cdbptr[0] == REQUEST_SENSE) {
8188 if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
8189 asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
8190 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
8191 AscMsgOutSDTR(asc_dvc,
8192 asc_dvc->
8193 sdtr_period_tbl[(sdtr_data >> 4) &
8194 (uchar)(asc_dvc->
8195 max_sdtr_index -
8196 1)],
8197 (uchar)(sdtr_data & (uchar)
8198 ASC_SYN_MAX_OFFSET));
8199 scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
8200 }
8201 }
8202 if (asc_dvc->in_critical_cnt != 0) {
8203 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
8204 return ASC_ERROR;
8205 }
8206 asc_dvc->in_critical_cnt++;
8207 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
8208 if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
8209 asc_dvc->in_critical_cnt--;
8210 return ASC_ERROR;
8211 }
8212 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
8213 asc_dvc->in_critical_cnt--;
8214 return ASC_ERROR;
8215 }
8216 if (sg_entry_cnt == 1) {
8217 scsiq->q1.data_addr = cpu_to_le32(sg_head->sg_list[0].addr);
8218 scsiq->q1.data_cnt = cpu_to_le32(sg_head->sg_list[0].bytes);
8219 scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
8220 }
8221 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
8222 }
8223 scsi_cmd = scsiq->cdbptr[0];
8224 disable_syn_offset_one_fix = false;
8225 if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
8226 !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
8227 if (scsiq->q1.cntl & QC_SG_HEAD) {
8228 data_cnt = 0;
8229 for (i = 0; i < sg_entry_cnt; i++) {
8230 data_cnt += le32_to_cpu(sg_head->sg_list[i].
8231 bytes);
8232 }
8233 } else {
8234 data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
8235 }
8236 if (data_cnt != 0UL) {
8237 if (data_cnt < 512UL) {
8238 disable_syn_offset_one_fix = true;
8239 } else {
8240 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST;
8241 i++) {
8242 disable_cmd =
8243 _syn_offset_one_disable_cmd[i];
8244 if (disable_cmd == 0xFF) {
8245 break;
8246 }
8247 if (scsi_cmd == disable_cmd) {
8248 disable_syn_offset_one_fix =
8249 true;
8250 break;
8251 }
8252 }
8253 }
8254 }
8255 }
8256 if (disable_syn_offset_one_fix) {
8257 scsiq->q2.tag_code &= ~SIMPLE_QUEUE_TAG;
8258 scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
8259 ASC_TAG_FLAG_DISABLE_DISCONNECT);
8260 } else {
8261 scsiq->q2.tag_code &= 0x27;
8262 }
8263 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
8264 if (asc_dvc->bug_fix_cntl) {
8265 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
8266 if ((scsi_cmd == READ_6) ||
8267 (scsi_cmd == READ_10)) {
8268 addr = le32_to_cpu(sg_head->
8269 sg_list
8270 [sg_entry_cnt_minus_one].
8271 addr) +
8272 le32_to_cpu(sg_head->
8273 sg_list
8274 [sg_entry_cnt_minus_one].
8275 bytes);
8276 extra_bytes =
8277 (uchar)((ushort)addr & 0x0003);
8278 if ((extra_bytes != 0)
8279 &&
8280 ((scsiq->q2.
8281 tag_code &
8282 ASC_TAG_FLAG_EXTRA_BYTES)
8283 == 0)) {
8284 scsiq->q2.tag_code |=
8285 ASC_TAG_FLAG_EXTRA_BYTES;
8286 scsiq->q1.extra_bytes =
8287 extra_bytes;
8288 data_cnt =
8289 le32_to_cpu(sg_head->
8290 sg_list
8291 [sg_entry_cnt_minus_one].
8292 bytes);
8293 data_cnt -= extra_bytes;
8294 sg_head->
8295 sg_list
8296 [sg_entry_cnt_minus_one].
8297 bytes =
8298 cpu_to_le32(data_cnt);
8299 }
8300 }
8301 }
8302 }
8303 sg_head->entry_to_copy = sg_head->entry_cnt;
8304 n_q_required = AscSgListToQueue(sg_entry_cnt);
8305 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
8306 (uint) n_q_required)
8307 || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
8308 if ((sta =
8309 AscSendScsiQueue(asc_dvc, scsiq,
8310 n_q_required)) == 1) {
8311 asc_dvc->in_critical_cnt--;
8312 return (sta);
8313 }
8314 }
8315 } else {
8316 if (asc_dvc->bug_fix_cntl) {
8317 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
8318 if ((scsi_cmd == READ_6) ||
8319 (scsi_cmd == READ_10)) {
8320 addr =
8321 le32_to_cpu(scsiq->q1.data_addr) +
8322 le32_to_cpu(scsiq->q1.data_cnt);
8323 extra_bytes =
8324 (uchar)((ushort)addr & 0x0003);
8325 if ((extra_bytes != 0)
8326 &&
8327 ((scsiq->q2.
8328 tag_code &
8329 ASC_TAG_FLAG_EXTRA_BYTES)
8330 == 0)) {
8331 data_cnt =
8332 le32_to_cpu(scsiq->q1.
8333 data_cnt);
8334 if (((ushort)data_cnt & 0x01FF)
8335 == 0) {
8336 scsiq->q2.tag_code |=
8337 ASC_TAG_FLAG_EXTRA_BYTES;
8338 data_cnt -= extra_bytes;
8339 scsiq->q1.data_cnt =
8340 cpu_to_le32
8341 (data_cnt);
8342 scsiq->q1.extra_bytes =
8343 extra_bytes;
8344 }
8345 }
8346 }
8347 }
8348 }
8349 n_q_required = 1;
8350 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
8351 ((scsiq->q1.cntl & QC_URGENT) != 0)) {
8352 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
8353 n_q_required)) == 1) {
8354 asc_dvc->in_critical_cnt--;
8355 return (sta);
8356 }
8357 }
8358 }
8359 asc_dvc->in_critical_cnt--;
8360 return (sta);
8361}
8362
8363
8364
8365
8366
8367
8368
8369
8370
8371
8372
8373
8374
8375
8376
8377
8378
8379
8380
8381
8382
8383
8384static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, adv_req_t *reqp)
8385{
8386 AdvPortAddr iop_base;
8387 ADV_CARR_T *new_carrp;
8388 ADV_SCSI_REQ_Q *scsiq = &reqp->scsi_req_q;
8389
8390
8391
8392
8393 if (scsiq->target_id > ADV_MAX_TID) {
8394 scsiq->host_status = QHSTA_M_INVALID_DEVICE;
8395 scsiq->done_status = QD_WITH_ERROR;
8396 return ADV_ERROR;
8397 }
8398
8399 iop_base = asc_dvc->iop_base;
8400
8401
8402
8403
8404
8405 new_carrp = adv_get_next_carrier(asc_dvc);
8406 if (!new_carrp) {
8407 ASC_DBG(1, "No free carriers\n");
8408 return ADV_BUSY;
8409 }
8410
8411 asc_dvc->carr_pending_cnt++;
8412
8413
8414 scsiq->scsiq_ptr = cpu_to_le32(scsiq->srb_tag);
8415 scsiq->scsiq_rptr = cpu_to_le32(reqp->req_addr);
8416
8417 scsiq->carr_va = asc_dvc->icq_sp->carr_va;
8418 scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
8419
8420
8421
8422
8423
8424
8425 asc_dvc->icq_sp->areq_vpa = scsiq->scsiq_rptr;
8426
8427
8428
8429
8430
8431
8432 asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
8433
8434
8435
8436
8437 asc_dvc->icq_sp = new_carrp;
8438
8439 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
8440 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
8441
8442
8443
8444 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
8445 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
8446
8447
8448
8449
8450
8451 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
8452 ADV_TICKLE_NOP);
8453 }
8454 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
8455
8456
8457
8458
8459 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
8460 le32_to_cpu(new_carrp->carr_pa));
8461 }
8462
8463 return ADV_SUCCESS;
8464}
8465
8466
8467
8468
8469static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
8470{
8471 int ret, err_code;
8472 struct asc_board *boardp = shost_priv(scp->device->host);
8473
8474 ASC_DBG(1, "scp 0x%p\n", scp);
8475
8476 if (ASC_NARROW_BOARD(boardp)) {
8477 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
8478 struct asc_scsi_q asc_scsi_q;
8479
8480 ret = asc_build_req(boardp, scp, &asc_scsi_q);
8481 if (ret != ASC_NOERROR) {
8482 ASC_STATS(scp->device->host, build_error);
8483 return ret;
8484 }
8485
8486 ret = AscExeScsiQueue(asc_dvc, &asc_scsi_q);
8487 kfree(asc_scsi_q.sg_head);
8488 err_code = asc_dvc->err_code;
8489 } else {
8490 ADV_DVC_VAR *adv_dvc = &boardp->dvc_var.adv_dvc_var;
8491 adv_req_t *adv_reqp;
8492
8493 switch (adv_build_req(boardp, scp, &adv_reqp)) {
8494 case ASC_NOERROR:
8495 ASC_DBG(3, "adv_build_req ASC_NOERROR\n");
8496 break;
8497 case ASC_BUSY:
8498 ASC_DBG(1, "adv_build_req ASC_BUSY\n");
8499
8500
8501
8502
8503
8504
8505 return ASC_BUSY;
8506 case ASC_ERROR:
8507 default:
8508 ASC_DBG(1, "adv_build_req ASC_ERROR\n");
8509 ASC_STATS(scp->device->host, build_error);
8510 return ASC_ERROR;
8511 }
8512
8513 ret = AdvExeScsiQueue(adv_dvc, adv_reqp);
8514 err_code = adv_dvc->err_code;
8515 }
8516
8517 switch (ret) {
8518 case ASC_NOERROR:
8519 ASC_STATS(scp->device->host, exe_noerror);
8520
8521
8522
8523
8524 boardp->reqcnt[scp->device->id]++;
8525 ASC_DBG(1, "ExeScsiQueue() ASC_NOERROR\n");
8526 break;
8527 case ASC_BUSY:
8528 ASC_DBG(1, "ExeScsiQueue() ASC_BUSY\n");
8529 ASC_STATS(scp->device->host, exe_busy);
8530 break;
8531 case ASC_ERROR:
8532 scmd_printk(KERN_ERR, scp, "ExeScsiQueue() ASC_ERROR, "
8533 "err_code 0x%x\n", err_code);
8534 ASC_STATS(scp->device->host, exe_error);
8535 scp->result = HOST_BYTE(DID_ERROR);
8536 break;
8537 default:
8538 scmd_printk(KERN_ERR, scp, "ExeScsiQueue() unknown, "
8539 "err_code 0x%x\n", err_code);
8540 ASC_STATS(scp->device->host, exe_unknown);
8541 scp->result = HOST_BYTE(DID_ERROR);
8542 break;
8543 }
8544
8545 ASC_DBG(1, "end\n");
8546 return ret;
8547}
8548
8549
8550
8551
8552
8553
8554
8555static int
8556advansys_queuecommand_lck(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
8557{
8558 struct Scsi_Host *shost = scp->device->host;
8559 int asc_res, result = 0;
8560
8561 ASC_STATS(shost, queuecommand);
8562 scp->scsi_done = done;
8563
8564 asc_res = asc_execute_scsi_cmnd(scp);
8565
8566 switch (asc_res) {
8567 case ASC_NOERROR:
8568 break;
8569 case ASC_BUSY:
8570 result = SCSI_MLQUEUE_HOST_BUSY;
8571 break;
8572 case ASC_ERROR:
8573 default:
8574 asc_scsi_done(scp);
8575 break;
8576 }
8577
8578 return result;
8579}
8580
8581static DEF_SCSI_QCMD(advansys_queuecommand)
8582
8583static ushort AscGetEisaChipCfg(PortAddr iop_base)
8584{
8585 PortAddr eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
8586 (PortAddr) (ASC_EISA_CFG_IOP_MASK);
8587 return inpw(eisa_cfg_iop);
8588}
8589
8590
8591
8592
8593
8594static unsigned short AscGetChipBiosAddress(PortAddr iop_base,
8595 unsigned short bus_type)
8596{
8597 unsigned short cfg_lsw;
8598 unsigned short bios_addr;
8599
8600
8601
8602
8603
8604
8605 if (bus_type & ASC_IS_PCI)
8606 return 0;
8607
8608 if ((bus_type & ASC_IS_EISA) != 0) {
8609 cfg_lsw = AscGetEisaChipCfg(iop_base);
8610 cfg_lsw &= 0x000F;
8611 bios_addr = ASC_BIOS_MIN_ADDR + cfg_lsw * ASC_BIOS_BANK_SIZE;
8612 return bios_addr;
8613 }
8614
8615 cfg_lsw = AscGetChipCfgLsw(iop_base);
8616
8617
8618
8619
8620 if (bus_type == ASC_IS_ISAPNP)
8621 cfg_lsw &= 0x7FFF;
8622 bios_addr = ASC_BIOS_MIN_ADDR + (cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE;
8623 return bios_addr;
8624}
8625
8626static uchar AscSetChipScsiID(PortAddr iop_base, uchar new_host_id)
8627{
8628 ushort cfg_lsw;
8629
8630 if (AscGetChipScsiID(iop_base) == new_host_id) {
8631 return (new_host_id);
8632 }
8633 cfg_lsw = AscGetChipCfgLsw(iop_base);
8634 cfg_lsw &= 0xF8FF;
8635 cfg_lsw |= (ushort)((new_host_id & ASC_MAX_TID) << 8);
8636 AscSetChipCfgLsw(iop_base, cfg_lsw);
8637 return (AscGetChipScsiID(iop_base));
8638}
8639
8640static unsigned char AscGetChipScsiCtrl(PortAddr iop_base)
8641{
8642 unsigned char sc;
8643
8644 AscSetBank(iop_base, 1);
8645 sc = inp(iop_base + IOP_REG_SC);
8646 AscSetBank(iop_base, 0);
8647 return sc;
8648}
8649
8650static unsigned char AscGetChipVersion(PortAddr iop_base,
8651 unsigned short bus_type)
8652{
8653 if (bus_type & ASC_IS_EISA) {
8654 PortAddr eisa_iop;
8655 unsigned char revision;
8656 eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
8657 (PortAddr) ASC_EISA_REV_IOP_MASK;
8658 revision = inp(eisa_iop);
8659 return ASC_CHIP_MIN_VER_EISA - 1 + revision;
8660 }
8661 return AscGetChipVerNo(iop_base);
8662}
8663
8664#ifdef CONFIG_ISA
8665static void AscEnableIsaDma(uchar dma_channel)
8666{
8667 if (dma_channel < 4) {
8668 outp(0x000B, (ushort)(0xC0 | dma_channel));
8669 outp(0x000A, dma_channel);
8670 } else if (dma_channel < 8) {
8671 outp(0x00D6, (ushort)(0xC0 | (dma_channel - 4)));
8672 outp(0x00D4, (ushort)(dma_channel - 4));
8673 }
8674}
8675#endif
8676
8677static int AscStopQueueExe(PortAddr iop_base)
8678{
8679 int count = 0;
8680
8681 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
8682 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
8683 ASC_STOP_REQ_RISC_STOP);
8684 do {
8685 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
8686 ASC_STOP_ACK_RISC_STOP) {
8687 return (1);
8688 }
8689 mdelay(100);
8690 } while (count++ < 20);
8691 }
8692 return (0);
8693}
8694
8695static unsigned int AscGetMaxDmaCount(ushort bus_type)
8696{
8697 if (bus_type & ASC_IS_ISA)
8698 return ASC_MAX_ISA_DMA_COUNT;
8699 else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
8700 return ASC_MAX_VL_DMA_COUNT;
8701 return ASC_MAX_PCI_DMA_COUNT;
8702}
8703
8704#ifdef CONFIG_ISA
8705static ushort AscGetIsaDmaChannel(PortAddr iop_base)
8706{
8707 ushort channel;
8708
8709 channel = AscGetChipCfgLsw(iop_base) & 0x0003;
8710 if (channel == 0x03)
8711 return (0);
8712 else if (channel == 0x00)
8713 return (7);
8714 return (channel + 4);
8715}
8716
8717static ushort AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel)
8718{
8719 ushort cfg_lsw;
8720 uchar value;
8721
8722 if ((dma_channel >= 5) && (dma_channel <= 7)) {
8723 if (dma_channel == 7)
8724 value = 0x00;
8725 else
8726 value = dma_channel - 4;
8727 cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
8728 cfg_lsw |= value;
8729 AscSetChipCfgLsw(iop_base, cfg_lsw);
8730 return (AscGetIsaDmaChannel(iop_base));
8731 }
8732 return 0;
8733}
8734
8735static uchar AscGetIsaDmaSpeed(PortAddr iop_base)
8736{
8737 uchar speed_value;
8738
8739 AscSetBank(iop_base, 1);
8740 speed_value = AscReadChipDmaSpeed(iop_base);
8741 speed_value &= 0x07;
8742 AscSetBank(iop_base, 0);
8743 return speed_value;
8744}
8745
8746static uchar AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value)
8747{
8748 speed_value &= 0x07;
8749 AscSetBank(iop_base, 1);
8750 AscWriteChipDmaSpeed(iop_base, speed_value);
8751 AscSetBank(iop_base, 0);
8752 return AscGetIsaDmaSpeed(iop_base);
8753}
8754#endif
8755
8756static void AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc)
8757{
8758 int i;
8759 PortAddr iop_base;
8760 uchar chip_version;
8761
8762 iop_base = asc_dvc->iop_base;
8763 asc_dvc->err_code = 0;
8764 if ((asc_dvc->bus_type &
8765 (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
8766 asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
8767 }
8768 AscSetChipControl(iop_base, CC_HALT);
8769 AscSetChipStatus(iop_base, 0);
8770 asc_dvc->bug_fix_cntl = 0;
8771 asc_dvc->pci_fix_asyn_xfer = 0;
8772 asc_dvc->pci_fix_asyn_xfer_always = 0;
8773
8774 asc_dvc->sdtr_done = 0;
8775 asc_dvc->cur_total_qng = 0;
8776 asc_dvc->is_in_int = false;
8777 asc_dvc->in_critical_cnt = 0;
8778 asc_dvc->last_q_shortage = 0;
8779 asc_dvc->use_tagged_qng = 0;
8780 asc_dvc->no_scam = 0;
8781 asc_dvc->unit_not_ready = 0;
8782 asc_dvc->queue_full_or_busy = 0;
8783 asc_dvc->redo_scam = 0;
8784 asc_dvc->res2 = 0;
8785 asc_dvc->min_sdtr_index = 0;
8786 asc_dvc->cfg->can_tagged_qng = 0;
8787 asc_dvc->cfg->cmd_qng_enabled = 0;
8788 asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
8789 asc_dvc->init_sdtr = 0;
8790 asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
8791 asc_dvc->scsi_reset_wait = 3;
8792 asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
8793 asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
8794 asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
8795 asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
8796 asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
8797 chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
8798 asc_dvc->cfg->chip_version = chip_version;
8799 asc_dvc->sdtr_period_tbl = asc_syn_xfer_period;
8800 asc_dvc->max_sdtr_index = 7;
8801 if ((asc_dvc->bus_type & ASC_IS_PCI) &&
8802 (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
8803 asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
8804 asc_dvc->sdtr_period_tbl = asc_syn_ultra_xfer_period;
8805 asc_dvc->max_sdtr_index = 15;
8806 if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) {
8807 AscSetExtraControl(iop_base,
8808 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
8809 } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
8810 AscSetExtraControl(iop_base,
8811 (SEC_ACTIVE_NEGATE |
8812 SEC_ENABLE_FILTER));
8813 }
8814 }
8815 if (asc_dvc->bus_type == ASC_IS_PCI) {
8816 AscSetExtraControl(iop_base,
8817 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
8818 }
8819
8820 asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
8821#ifdef CONFIG_ISA
8822 if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
8823 if (chip_version >= ASC_CHIP_MIN_VER_ISA_PNP) {
8824 AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
8825 asc_dvc->bus_type = ASC_IS_ISAPNP;
8826 }
8827 asc_dvc->cfg->isa_dma_channel =
8828 (uchar)AscGetIsaDmaChannel(iop_base);
8829 }
8830#endif
8831 for (i = 0; i <= ASC_MAX_TID; i++) {
8832 asc_dvc->cur_dvc_qng[i] = 0;
8833 asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
8834 asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *)0L;
8835 asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *)0L;
8836 asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
8837 }
8838}
8839
8840static int AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg)
8841{
8842 int retry;
8843
8844 for (retry = 0; retry < ASC_EEP_MAX_RETRY; retry++) {
8845 unsigned char read_back;
8846 AscSetChipEEPCmd(iop_base, cmd_reg);
8847 mdelay(1);
8848 read_back = AscGetChipEEPCmd(iop_base);
8849 if (read_back == cmd_reg)
8850 return 1;
8851 }
8852 return 0;
8853}
8854
8855static void AscWaitEEPRead(void)
8856{
8857 mdelay(1);
8858}
8859
8860static ushort AscReadEEPWord(PortAddr iop_base, uchar addr)
8861{
8862 ushort read_wval;
8863 uchar cmd_reg;
8864
8865 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
8866 AscWaitEEPRead();
8867 cmd_reg = addr | ASC_EEP_CMD_READ;
8868 AscWriteEEPCmdReg(iop_base, cmd_reg);
8869 AscWaitEEPRead();
8870 read_wval = AscGetChipEEPData(iop_base);
8871 AscWaitEEPRead();
8872 return read_wval;
8873}
8874
8875static ushort AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf,
8876 ushort bus_type)
8877{
8878 ushort wval;
8879 ushort sum;
8880 ushort *wbuf;
8881 int cfg_beg;
8882 int cfg_end;
8883 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
8884 int s_addr;
8885
8886 wbuf = (ushort *)cfg_buf;
8887 sum = 0;
8888
8889 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
8890 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
8891 sum += *wbuf;
8892 }
8893 if (bus_type & ASC_IS_VL) {
8894 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
8895 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
8896 } else {
8897 cfg_beg = ASC_EEP_DVC_CFG_BEG;
8898 cfg_end = ASC_EEP_MAX_DVC_ADDR;
8899 }
8900 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
8901 wval = AscReadEEPWord(iop_base, (uchar)s_addr);
8902 if (s_addr <= uchar_end_in_config) {
8903
8904
8905
8906
8907 *wbuf = le16_to_cpu(wval);
8908 } else {
8909
8910 *wbuf = wval;
8911 }
8912 sum += wval;
8913 }
8914
8915
8916
8917
8918 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
8919 return sum;
8920}
8921
8922static int AscTestExternalLram(ASC_DVC_VAR *asc_dvc)
8923{
8924 PortAddr iop_base;
8925 ushort q_addr;
8926 ushort saved_word;
8927 int sta;
8928
8929 iop_base = asc_dvc->iop_base;
8930 sta = 0;
8931 q_addr = ASC_QNO_TO_QADDR(241);
8932 saved_word = AscReadLramWord(iop_base, q_addr);
8933 AscSetChipLramAddr(iop_base, q_addr);
8934 AscSetChipLramData(iop_base, 0x55AA);
8935 mdelay(10);
8936 AscSetChipLramAddr(iop_base, q_addr);
8937 if (AscGetChipLramData(iop_base) == 0x55AA) {
8938 sta = 1;
8939 AscWriteLramWord(iop_base, q_addr, saved_word);
8940 }
8941 return (sta);
8942}
8943
8944static void AscWaitEEPWrite(void)
8945{
8946 mdelay(20);
8947}
8948
8949static int AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg)
8950{
8951 ushort read_back;
8952 int retry;
8953
8954 retry = 0;
8955 while (true) {
8956 AscSetChipEEPData(iop_base, data_reg);
8957 mdelay(1);
8958 read_back = AscGetChipEEPData(iop_base);
8959 if (read_back == data_reg) {
8960 return (1);
8961 }
8962 if (retry++ > ASC_EEP_MAX_RETRY) {
8963 return (0);
8964 }
8965 }
8966}
8967
8968static ushort AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val)
8969{
8970 ushort read_wval;
8971
8972 read_wval = AscReadEEPWord(iop_base, addr);
8973 if (read_wval != word_val) {
8974 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
8975 AscWaitEEPRead();
8976 AscWriteEEPDataReg(iop_base, word_val);
8977 AscWaitEEPRead();
8978 AscWriteEEPCmdReg(iop_base,
8979 (uchar)((uchar)ASC_EEP_CMD_WRITE | addr));
8980 AscWaitEEPWrite();
8981 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
8982 AscWaitEEPRead();
8983 return (AscReadEEPWord(iop_base, addr));
8984 }
8985 return (read_wval);
8986}
8987
8988static int AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf,
8989 ushort bus_type)
8990{
8991 int n_error;
8992 ushort *wbuf;
8993 ushort word;
8994 ushort sum;
8995 int s_addr;
8996 int cfg_beg;
8997 int cfg_end;
8998 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
8999
9000 wbuf = (ushort *)cfg_buf;
9001 n_error = 0;
9002 sum = 0;
9003
9004 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
9005 sum += *wbuf;
9006 if (*wbuf != AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
9007 n_error++;
9008 }
9009 }
9010 if (bus_type & ASC_IS_VL) {
9011 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
9012 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
9013 } else {
9014 cfg_beg = ASC_EEP_DVC_CFG_BEG;
9015 cfg_end = ASC_EEP_MAX_DVC_ADDR;
9016 }
9017 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
9018 if (s_addr <= uchar_end_in_config) {
9019
9020
9021
9022
9023 word = cpu_to_le16(*wbuf);
9024 if (word !=
9025 AscWriteEEPWord(iop_base, (uchar)s_addr, word)) {
9026 n_error++;
9027 }
9028 } else {
9029
9030 if (*wbuf !=
9031 AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
9032 n_error++;
9033 }
9034 }
9035 sum += *wbuf;
9036 }
9037
9038 *wbuf = sum;
9039 if (sum != AscWriteEEPWord(iop_base, (uchar)s_addr, sum)) {
9040 n_error++;
9041 }
9042
9043
9044 wbuf = (ushort *)cfg_buf;
9045
9046
9047
9048 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
9049 if (*wbuf != AscReadEEPWord(iop_base, (uchar)s_addr)) {
9050 n_error++;
9051 }
9052 }
9053 if (bus_type & ASC_IS_VL) {
9054 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
9055 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
9056 } else {
9057 cfg_beg = ASC_EEP_DVC_CFG_BEG;
9058 cfg_end = ASC_EEP_MAX_DVC_ADDR;
9059 }
9060 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
9061 if (s_addr <= uchar_end_in_config) {
9062
9063
9064
9065
9066 word =
9067 le16_to_cpu(AscReadEEPWord
9068 (iop_base, (uchar)s_addr));
9069 } else {
9070
9071 word = AscReadEEPWord(iop_base, (uchar)s_addr);
9072 }
9073 if (*wbuf != word) {
9074 n_error++;
9075 }
9076 }
9077
9078 if (AscReadEEPWord(iop_base, (uchar)s_addr) != sum) {
9079 n_error++;
9080 }
9081 return n_error;
9082}
9083
9084static int AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf,
9085 ushort bus_type)
9086{
9087 int retry;
9088 int n_error;
9089
9090 retry = 0;
9091 while (true) {
9092 if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
9093 bus_type)) == 0) {
9094 break;
9095 }
9096 if (++retry > ASC_EEP_MAX_RETRY) {
9097 break;
9098 }
9099 }
9100 return n_error;
9101}
9102
9103static int AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
9104{
9105 ASCEEP_CONFIG eep_config_buf;
9106 ASCEEP_CONFIG *eep_config;
9107 PortAddr iop_base;
9108 ushort chksum;
9109 ushort warn_code;
9110 ushort cfg_msw, cfg_lsw;
9111 int i;
9112 int write_eep = 0;
9113
9114 iop_base = asc_dvc->iop_base;
9115 warn_code = 0;
9116 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
9117 AscStopQueueExe(iop_base);
9118 if ((AscStopChip(iop_base)) ||
9119 (AscGetChipScsiCtrl(iop_base) != 0)) {
9120 asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
9121 AscResetChipAndScsiBus(asc_dvc);
9122 mdelay(asc_dvc->scsi_reset_wait * 1000);
9123 }
9124 if (!AscIsChipHalted(iop_base)) {
9125 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
9126 return (warn_code);
9127 }
9128 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
9129 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
9130 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
9131 return (warn_code);
9132 }
9133 eep_config = (ASCEEP_CONFIG *)&eep_config_buf;
9134 cfg_msw = AscGetChipCfgMsw(iop_base);
9135 cfg_lsw = AscGetChipCfgLsw(iop_base);
9136 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
9137 cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
9138 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
9139 AscSetChipCfgMsw(iop_base, cfg_msw);
9140 }
9141 chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
9142 ASC_DBG(1, "chksum 0x%x\n", chksum);
9143 if (chksum == 0) {
9144 chksum = 0xaa55;
9145 }
9146 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
9147 warn_code |= ASC_WARN_AUTO_CONFIG;
9148 if (asc_dvc->cfg->chip_version == 3) {
9149 if (eep_config->cfg_lsw != cfg_lsw) {
9150 warn_code |= ASC_WARN_EEPROM_RECOVER;
9151 eep_config->cfg_lsw =
9152 AscGetChipCfgLsw(iop_base);
9153 }
9154 if (eep_config->cfg_msw != cfg_msw) {
9155 warn_code |= ASC_WARN_EEPROM_RECOVER;
9156 eep_config->cfg_msw =
9157 AscGetChipCfgMsw(iop_base);
9158 }
9159 }
9160 }
9161 eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
9162 eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
9163 ASC_DBG(1, "eep_config->chksum 0x%x\n", eep_config->chksum);
9164 if (chksum != eep_config->chksum) {
9165 if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
9166 ASC_CHIP_VER_PCI_ULTRA_3050) {
9167 ASC_DBG(1, "chksum error ignored; EEPROM-less board\n");
9168 eep_config->init_sdtr = 0xFF;
9169 eep_config->disc_enable = 0xFF;
9170 eep_config->start_motor = 0xFF;
9171 eep_config->use_cmd_qng = 0;
9172 eep_config->max_total_qng = 0xF0;
9173 eep_config->max_tag_qng = 0x20;
9174 eep_config->cntl = 0xBFFF;
9175 ASC_EEP_SET_CHIP_ID(eep_config, 7);
9176 eep_config->no_scam = 0;
9177 eep_config->adapter_info[0] = 0;
9178 eep_config->adapter_info[1] = 0;
9179 eep_config->adapter_info[2] = 0;
9180 eep_config->adapter_info[3] = 0;
9181 eep_config->adapter_info[4] = 0;
9182
9183 eep_config->adapter_info[5] = 0xBB;
9184 } else {
9185 ASC_PRINT
9186 ("AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
9187 write_eep = 1;
9188 warn_code |= ASC_WARN_EEPROM_CHKSUM;
9189 }
9190 }
9191 asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
9192 asc_dvc->cfg->disc_enable = eep_config->disc_enable;
9193 asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
9194 asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
9195 asc_dvc->start_motor = eep_config->start_motor;
9196 asc_dvc->dvc_cntl = eep_config->cntl;
9197 asc_dvc->no_scam = eep_config->no_scam;
9198 asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
9199 asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
9200 asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
9201 asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
9202 asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
9203 asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
9204 if (!AscTestExternalLram(asc_dvc)) {
9205 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) ==
9206 ASC_IS_PCI_ULTRA)) {
9207 eep_config->max_total_qng =
9208 ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
9209 eep_config->max_tag_qng =
9210 ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
9211 } else {
9212 eep_config->cfg_msw |= 0x0800;
9213 cfg_msw |= 0x0800;
9214 AscSetChipCfgMsw(iop_base, cfg_msw);
9215 eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
9216 eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
9217 }
9218 } else {
9219 }
9220 if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
9221 eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
9222 }
9223 if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
9224 eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
9225 }
9226 if (eep_config->max_tag_qng > eep_config->max_total_qng) {
9227 eep_config->max_tag_qng = eep_config->max_total_qng;
9228 }
9229 if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
9230 eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
9231 }
9232 asc_dvc->max_total_qng = eep_config->max_total_qng;
9233 if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
9234 eep_config->use_cmd_qng) {
9235 eep_config->disc_enable = eep_config->use_cmd_qng;
9236 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
9237 }
9238 ASC_EEP_SET_CHIP_ID(eep_config,
9239 ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
9240 asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
9241 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
9242 !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
9243 asc_dvc->min_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
9244 }
9245
9246 for (i = 0; i <= ASC_MAX_TID; i++) {
9247 asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
9248 asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
9249 asc_dvc->cfg->sdtr_period_offset[i] =
9250 (uchar)(ASC_DEF_SDTR_OFFSET |
9251 (asc_dvc->min_sdtr_index << 4));
9252 }
9253 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
9254 if (write_eep) {
9255 if ((i = AscSetEEPConfig(iop_base, eep_config,
9256 asc_dvc->bus_type)) != 0) {
9257 ASC_PRINT1
9258 ("AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n",
9259 i);
9260 } else {
9261 ASC_PRINT
9262 ("AscInitFromEEP: Successfully re-wrote EEPROM.\n");
9263 }
9264 }
9265 return (warn_code);
9266}
9267
9268static int AscInitGetConfig(struct Scsi_Host *shost)
9269{
9270 struct asc_board *board = shost_priv(shost);
9271 ASC_DVC_VAR *asc_dvc = &board->dvc_var.asc_dvc_var;
9272 unsigned short warn_code = 0;
9273
9274 asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
9275 if (asc_dvc->err_code != 0)
9276 return asc_dvc->err_code;
9277
9278 if (AscFindSignature(asc_dvc->iop_base)) {
9279 AscInitAscDvcVar(asc_dvc);
9280 warn_code = AscInitFromEEP(asc_dvc);
9281 asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
9282 if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT)
9283 asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
9284 } else {
9285 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
9286 }
9287
9288 switch (warn_code) {
9289 case 0:
9290 break;
9291 case ASC_WARN_IO_PORT_ROTATE:
9292 shost_printk(KERN_WARNING, shost, "I/O port address "
9293 "modified\n");
9294 break;
9295 case ASC_WARN_AUTO_CONFIG:
9296 shost_printk(KERN_WARNING, shost, "I/O port increment switch "
9297 "enabled\n");
9298 break;
9299 case ASC_WARN_EEPROM_CHKSUM:
9300 shost_printk(KERN_WARNING, shost, "EEPROM checksum error\n");
9301 break;
9302 case ASC_WARN_IRQ_MODIFIED:
9303 shost_printk(KERN_WARNING, shost, "IRQ modified\n");
9304 break;
9305 case ASC_WARN_CMD_QNG_CONFLICT:
9306 shost_printk(KERN_WARNING, shost, "tag queuing enabled w/o "
9307 "disconnects\n");
9308 break;
9309 default:
9310 shost_printk(KERN_WARNING, shost, "unknown warning: 0x%x\n",
9311 warn_code);
9312 break;
9313 }
9314
9315 if (asc_dvc->err_code != 0)
9316 shost_printk(KERN_ERR, shost, "error 0x%x at init_state "
9317 "0x%x\n", asc_dvc->err_code, asc_dvc->init_state);
9318
9319 return asc_dvc->err_code;
9320}
9321
9322static int AscInitSetConfig(struct pci_dev *pdev, struct Scsi_Host *shost)
9323{
9324 struct asc_board *board = shost_priv(shost);
9325 ASC_DVC_VAR *asc_dvc = &board->dvc_var.asc_dvc_var;
9326 PortAddr iop_base = asc_dvc->iop_base;
9327 unsigned short cfg_msw;
9328 unsigned short warn_code = 0;
9329
9330 asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
9331 if (asc_dvc->err_code != 0)
9332 return asc_dvc->err_code;
9333 if (!AscFindSignature(asc_dvc->iop_base)) {
9334 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
9335 return asc_dvc->err_code;
9336 }
9337
9338 cfg_msw = AscGetChipCfgMsw(iop_base);
9339 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
9340 cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
9341 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
9342 AscSetChipCfgMsw(iop_base, cfg_msw);
9343 }
9344 if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
9345 asc_dvc->cfg->cmd_qng_enabled) {
9346 asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
9347 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
9348 }
9349 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
9350 warn_code |= ASC_WARN_AUTO_CONFIG;
9351 }
9352#ifdef CONFIG_PCI
9353 if (asc_dvc->bus_type & ASC_IS_PCI) {
9354 cfg_msw &= 0xFFC0;
9355 AscSetChipCfgMsw(iop_base, cfg_msw);
9356 if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
9357 } else {
9358 if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
9359 (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
9360 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
9361 asc_dvc->bug_fix_cntl |=
9362 ASC_BUG_FIX_ASYN_USE_SYN;
9363 }
9364 }
9365 } else
9366#endif
9367 if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
9368 if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
9369 == ASC_CHIP_VER_ASYN_BUG) {
9370 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
9371 }
9372 }
9373 if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
9374 asc_dvc->cfg->chip_scsi_id) {
9375 asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
9376 }
9377#ifdef CONFIG_ISA
9378 if (asc_dvc->bus_type & ASC_IS_ISA) {
9379 AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
9380 AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
9381 }
9382#endif
9383
9384 asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
9385
9386 switch (warn_code) {
9387 case 0:
9388 break;
9389 case ASC_WARN_IO_PORT_ROTATE:
9390 shost_printk(KERN_WARNING, shost, "I/O port address "
9391 "modified\n");
9392 break;
9393 case ASC_WARN_AUTO_CONFIG:
9394 shost_printk(KERN_WARNING, shost, "I/O port increment switch "
9395 "enabled\n");
9396 break;
9397 case ASC_WARN_EEPROM_CHKSUM:
9398 shost_printk(KERN_WARNING, shost, "EEPROM checksum error\n");
9399 break;
9400 case ASC_WARN_IRQ_MODIFIED:
9401 shost_printk(KERN_WARNING, shost, "IRQ modified\n");
9402 break;
9403 case ASC_WARN_CMD_QNG_CONFLICT:
9404 shost_printk(KERN_WARNING, shost, "tag queuing w/o "
9405 "disconnects\n");
9406 break;
9407 default:
9408 shost_printk(KERN_WARNING, shost, "unknown warning: 0x%x\n",
9409 warn_code);
9410 break;
9411 }
9412
9413 if (asc_dvc->err_code != 0)
9414 shost_printk(KERN_ERR, shost, "error 0x%x at init_state "
9415 "0x%x\n", asc_dvc->err_code, asc_dvc->init_state);
9416
9417 return asc_dvc->err_code;
9418}
9419
9420
9421
9422
9423
9424
9425
9426
9427
9428
9429
9430
9431
9432
9433
9434
9435
9436#ifdef CONFIG_PCI
9437static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config = {
9438 ADV_EEPROM_BIOS_ENABLE,
9439 0x0000,
9440 0xFFFF,
9441 0xFFFF,
9442 0xFFFF,
9443 0xFFFF,
9444 0xFFFF,
9445 0xFFFF,
9446 0,
9447 7,
9448 0,
9449 3,
9450 0,
9451 0,
9452 0,
9453 0xFFE7,
9454 0xFFFF,
9455 0,
9456 ASC_DEF_MAX_HOST_QNG,
9457 ASC_DEF_MAX_DVC_QNG,
9458 0,
9459 0,
9460 0,
9461 0,
9462 0,
9463 0,
9464 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
9465 ,
9466 0,
9467 0,
9468 0,
9469 0,
9470 0,
9471 0,
9472 0
9473};
9474
9475static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar = {
9476 0,
9477 0,
9478 0,
9479 0,
9480 0,
9481 0,
9482 0,
9483 0,
9484 0,
9485 1,
9486 1,
9487 1,
9488 1,
9489 1,
9490 1,
9491 0,
9492 0,
9493 0,
9494 1,
9495 1,
9496 0,
9497 0,
9498 0,
9499 0,
9500 0,
9501 0,
9502 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
9503 ,
9504 0,
9505 0,
9506 0,
9507 0,
9508 0,
9509 0,
9510 0
9511};
9512
9513static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config = {
9514 ADV_EEPROM_BIOS_ENABLE,
9515 0x0000,
9516 0xFFFF,
9517 0xFFFF,
9518 0x4444,
9519 0xFFFF,
9520 0xFFFF,
9521 0xFFFF,
9522 0,
9523 7,
9524 0,
9525 3,
9526 0,
9527 0,
9528 0,
9529 0xFFE7,
9530 0x4444,
9531 0x4444,
9532 ASC_DEF_MAX_HOST_QNG,
9533 ASC_DEF_MAX_DVC_QNG,
9534 0,
9535 0x4444,
9536 0,
9537 0,
9538 0,
9539 0,
9540 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
9541 ,
9542 0,
9543 0,
9544 0,
9545 0,
9546 0,
9547 0,
9548 0,
9549 0,
9550 0,
9551 0,
9552 0,
9553 0,
9554 0,
9555 0,
9556 0,
9557 0,
9558 0,
9559 0,
9560 0,
9561 0,
9562 0,
9563 0,
9564 0,
9565 0,
9566 0,
9567 0,
9568 0,
9569 0,
9570 PCI_VENDOR_ID_ASP,
9571 PCI_DEVICE_ID_38C0800_REV1,
9572 0,
9573 0,
9574 0,
9575 0
9576};
9577
9578static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar = {
9579 0,
9580 0,
9581 0,
9582 0,
9583 0,
9584 0,
9585 0,
9586 0,
9587 0,
9588 1,
9589 1,
9590 1,
9591 1,
9592 1,
9593 1,
9594 0,
9595 0,
9596 0,
9597 1,
9598 1,
9599 0,
9600 0,
9601 0,
9602 0,
9603 0,
9604 0,
9605 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
9606 ,
9607 0,
9608 0,
9609 0,
9610 0,
9611 0,
9612 0,
9613 0,
9614 0,
9615 0,
9616 0,
9617 0,
9618 0,
9619 0,
9620 0,
9621 0,
9622 0,
9623 0,
9624 0,
9625 0,
9626 0,
9627 0,
9628 0,
9629 0,
9630 0,
9631 0,
9632 0,
9633 0,
9634 0,
9635 0,
9636 0,
9637 0,
9638 0,
9639 0,
9640 0
9641};
9642
9643static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config = {
9644 ADV_EEPROM_BIOS_ENABLE,
9645 0x0000,
9646 0xFFFF,
9647 0xFFFF,
9648 0x5555,
9649 0xFFFF,
9650 0xFFFF,
9651 0xFFFF,
9652 0,
9653 7,
9654 0,
9655 3,
9656 0,
9657 0,
9658 0,
9659 0xFFE7,
9660 0x5555,
9661 0x5555,
9662 ASC_DEF_MAX_HOST_QNG,
9663 ASC_DEF_MAX_DVC_QNG,
9664 0,
9665 0x5555,
9666 0,
9667 0,
9668 0,
9669 0,
9670 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
9671 ,
9672 0,
9673 0,
9674 0,
9675 0,
9676 0,
9677 0,
9678 0,
9679 0,
9680 0,
9681 0,
9682 0,
9683 0,
9684 0,
9685 0,
9686 0,
9687 0,
9688 0,
9689 0,
9690 0,
9691 0,
9692 0,
9693 0,
9694 0,
9695 0,
9696 0,
9697 0,
9698 0,
9699 0,
9700 PCI_VENDOR_ID_ASP,
9701 PCI_DEVICE_ID_38C1600_REV1,
9702 0,
9703 0,
9704 0,
9705 0
9706};
9707
9708static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar = {
9709 0,
9710 0,
9711 0,
9712 0,
9713 0,
9714 0,
9715 0,
9716 0,
9717 0,
9718 1,
9719 1,
9720 1,
9721 1,
9722 1,
9723 1,
9724 0,
9725 0,
9726 0,
9727 1,
9728 1,
9729 0,
9730 0,
9731 0,
9732 0,
9733 0,
9734 0,
9735 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
9736 ,
9737 0,
9738 0,
9739 0,
9740 0,
9741 0,
9742 0,
9743 0,
9744 0,
9745 0,
9746 0,
9747 0,
9748 0,
9749 0,
9750 0,
9751 0,
9752 0,
9753 0,
9754 0,
9755 0,
9756 0,
9757 0,
9758 0,
9759 0,
9760 0,
9761 0,
9762 0,
9763 0,
9764 0,
9765 0,
9766 0,
9767 0,
9768 0,
9769 0,
9770 0
9771};
9772
9773
9774
9775
9776static void AdvWaitEEPCmd(AdvPortAddr iop_base)
9777{
9778 int eep_delay_ms;
9779
9780 for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++) {
9781 if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) &
9782 ASC_EEP_CMD_DONE) {
9783 break;
9784 }
9785 mdelay(1);
9786 }
9787 if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) ==
9788 0)
9789 BUG();
9790}
9791
9792
9793
9794
9795static ushort AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
9796{
9797 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
9798 ASC_EEP_CMD_READ | eep_word_addr);
9799 AdvWaitEEPCmd(iop_base);
9800 return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
9801}
9802
9803
9804
9805
9806static void AdvSet3550EEPConfig(AdvPortAddr iop_base,
9807 ADVEEP_3550_CONFIG *cfg_buf)
9808{
9809 ushort *wbuf;
9810 ushort addr, chksum;
9811 ushort *charfields;
9812
9813 wbuf = (ushort *)cfg_buf;
9814 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
9815 chksum = 0;
9816
9817 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
9818 AdvWaitEEPCmd(iop_base);
9819
9820
9821
9822
9823 for (addr = ADV_EEP_DVC_CFG_BEGIN;
9824 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
9825 ushort word;
9826
9827 if (*charfields++) {
9828 word = cpu_to_le16(*wbuf);
9829 } else {
9830 word = *wbuf;
9831 }
9832 chksum += *wbuf;
9833 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
9834 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
9835 ASC_EEP_CMD_WRITE | addr);
9836 AdvWaitEEPCmd(iop_base);
9837 mdelay(ADV_EEP_DELAY_MS);
9838 }
9839
9840
9841
9842
9843 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
9844 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
9845 AdvWaitEEPCmd(iop_base);
9846 wbuf++;
9847 charfields++;
9848
9849
9850
9851
9852 for (addr = ADV_EEP_DVC_CTL_BEGIN;
9853 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
9854 ushort word;
9855
9856 if (*charfields++) {
9857 word = cpu_to_le16(*wbuf);
9858 } else {
9859 word = *wbuf;
9860 }
9861 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
9862 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
9863 ASC_EEP_CMD_WRITE | addr);
9864 AdvWaitEEPCmd(iop_base);
9865 }
9866 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
9867 AdvWaitEEPCmd(iop_base);
9868}
9869
9870
9871
9872
9873static void AdvSet38C0800EEPConfig(AdvPortAddr iop_base,
9874 ADVEEP_38C0800_CONFIG *cfg_buf)
9875{
9876 ushort *wbuf;
9877 ushort *charfields;
9878 ushort addr, chksum;
9879
9880 wbuf = (ushort *)cfg_buf;
9881 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
9882 chksum = 0;
9883
9884 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
9885 AdvWaitEEPCmd(iop_base);
9886
9887
9888
9889
9890 for (addr = ADV_EEP_DVC_CFG_BEGIN;
9891 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
9892 ushort word;
9893
9894 if (*charfields++) {
9895 word = cpu_to_le16(*wbuf);
9896 } else {
9897 word = *wbuf;
9898 }
9899 chksum += *wbuf;
9900 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
9901 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
9902 ASC_EEP_CMD_WRITE | addr);
9903 AdvWaitEEPCmd(iop_base);
9904 mdelay(ADV_EEP_DELAY_MS);
9905 }
9906
9907
9908
9909
9910 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
9911 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
9912 AdvWaitEEPCmd(iop_base);
9913 wbuf++;
9914 charfields++;
9915
9916
9917
9918
9919 for (addr = ADV_EEP_DVC_CTL_BEGIN;
9920 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
9921 ushort word;
9922
9923 if (*charfields++) {
9924 word = cpu_to_le16(*wbuf);
9925 } else {
9926 word = *wbuf;
9927 }
9928 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
9929 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
9930 ASC_EEP_CMD_WRITE | addr);
9931 AdvWaitEEPCmd(iop_base);
9932 }
9933 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
9934 AdvWaitEEPCmd(iop_base);
9935}
9936
9937
9938
9939
9940static void AdvSet38C1600EEPConfig(AdvPortAddr iop_base,
9941 ADVEEP_38C1600_CONFIG *cfg_buf)
9942{
9943 ushort *wbuf;
9944 ushort *charfields;
9945 ushort addr, chksum;
9946
9947 wbuf = (ushort *)cfg_buf;
9948 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
9949 chksum = 0;
9950
9951 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
9952 AdvWaitEEPCmd(iop_base);
9953
9954
9955
9956
9957 for (addr = ADV_EEP_DVC_CFG_BEGIN;
9958 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
9959 ushort word;
9960
9961 if (*charfields++) {
9962 word = cpu_to_le16(*wbuf);
9963 } else {
9964 word = *wbuf;
9965 }
9966 chksum += *wbuf;
9967 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
9968 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
9969 ASC_EEP_CMD_WRITE | addr);
9970 AdvWaitEEPCmd(iop_base);
9971 mdelay(ADV_EEP_DELAY_MS);
9972 }
9973
9974
9975
9976
9977 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
9978 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
9979 AdvWaitEEPCmd(iop_base);
9980 wbuf++;
9981 charfields++;
9982
9983
9984
9985
9986 for (addr = ADV_EEP_DVC_CTL_BEGIN;
9987 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
9988 ushort word;
9989
9990 if (*charfields++) {
9991 word = cpu_to_le16(*wbuf);
9992 } else {
9993 word = *wbuf;
9994 }
9995 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
9996 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
9997 ASC_EEP_CMD_WRITE | addr);
9998 AdvWaitEEPCmd(iop_base);
9999 }
10000 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
10001 AdvWaitEEPCmd(iop_base);
10002}
10003
10004
10005
10006
10007
10008
10009static ushort AdvGet3550EEPConfig(AdvPortAddr iop_base,
10010 ADVEEP_3550_CONFIG *cfg_buf)
10011{
10012 ushort wval, chksum;
10013 ushort *wbuf;
10014 int eep_addr;
10015 ushort *charfields;
10016
10017 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
10018 wbuf = (ushort *)cfg_buf;
10019 chksum = 0;
10020
10021 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
10022 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
10023 wval = AdvReadEEPWord(iop_base, eep_addr);
10024 chksum += wval;
10025 if (*charfields++) {
10026 *wbuf = le16_to_cpu(wval);
10027 } else {
10028 *wbuf = wval;
10029 }
10030 }
10031
10032 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
10033 wbuf++;
10034 charfields++;
10035
10036
10037 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
10038 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
10039 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
10040 if (*charfields++) {
10041 *wbuf = le16_to_cpu(*wbuf);
10042 }
10043 }
10044 return chksum;
10045}
10046
10047
10048
10049
10050
10051
10052static ushort AdvGet38C0800EEPConfig(AdvPortAddr iop_base,
10053 ADVEEP_38C0800_CONFIG *cfg_buf)
10054{
10055 ushort wval, chksum;
10056 ushort *wbuf;
10057 int eep_addr;
10058 ushort *charfields;
10059
10060 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
10061 wbuf = (ushort *)cfg_buf;
10062 chksum = 0;
10063
10064 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
10065 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
10066 wval = AdvReadEEPWord(iop_base, eep_addr);
10067 chksum += wval;
10068 if (*charfields++) {
10069 *wbuf = le16_to_cpu(wval);
10070 } else {
10071 *wbuf = wval;
10072 }
10073 }
10074
10075 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
10076 wbuf++;
10077 charfields++;
10078
10079
10080 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
10081 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
10082 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
10083 if (*charfields++) {
10084 *wbuf = le16_to_cpu(*wbuf);
10085 }
10086 }
10087 return chksum;
10088}
10089
10090
10091
10092
10093
10094
10095static ushort AdvGet38C1600EEPConfig(AdvPortAddr iop_base,
10096 ADVEEP_38C1600_CONFIG *cfg_buf)
10097{
10098 ushort wval, chksum;
10099 ushort *wbuf;
10100 int eep_addr;
10101 ushort *charfields;
10102
10103 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
10104 wbuf = (ushort *)cfg_buf;
10105 chksum = 0;
10106
10107 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
10108 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
10109 wval = AdvReadEEPWord(iop_base, eep_addr);
10110 chksum += wval;
10111 if (*charfields++) {
10112 *wbuf = le16_to_cpu(wval);
10113 } else {
10114 *wbuf = wval;
10115 }
10116 }
10117
10118 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
10119 wbuf++;
10120 charfields++;
10121
10122
10123 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
10124 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
10125 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
10126 if (*charfields++) {
10127 *wbuf = le16_to_cpu(*wbuf);
10128 }
10129 }
10130 return chksum;
10131}
10132
10133
10134
10135
10136
10137
10138
10139
10140
10141
10142
10143
10144
10145static int AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
10146{
10147 AdvPortAddr iop_base;
10148 ushort warn_code;
10149 ADVEEP_3550_CONFIG eep_config;
10150
10151 iop_base = asc_dvc->iop_base;
10152
10153 warn_code = 0;
10154
10155
10156
10157
10158
10159
10160 if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum) {
10161 warn_code |= ASC_WARN_EEPROM_CHKSUM;
10162
10163
10164
10165
10166 memcpy(&eep_config, &Default_3550_EEPROM_Config,
10167 sizeof(ADVEEP_3550_CONFIG));
10168
10169
10170
10171
10172
10173 eep_config.serial_number_word3 =
10174 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
10175
10176 eep_config.serial_number_word2 =
10177 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
10178
10179 eep_config.serial_number_word1 =
10180 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
10181
10182 AdvSet3550EEPConfig(iop_base, &eep_config);
10183 }
10184
10185
10186
10187
10188
10189
10190 asc_dvc->wdtr_able = eep_config.wdtr_able;
10191 asc_dvc->sdtr_able = eep_config.sdtr_able;
10192 asc_dvc->ultra_able = eep_config.ultra_able;
10193 asc_dvc->tagqng_able = eep_config.tagqng_able;
10194 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
10195 asc_dvc->max_host_qng = eep_config.max_host_qng;
10196 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
10197 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
10198 asc_dvc->start_motor = eep_config.start_motor;
10199 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
10200 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
10201 asc_dvc->no_scam = eep_config.scam_tolerant;
10202 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
10203 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
10204 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
10205
10206
10207
10208
10209
10210 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
10211 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
10212 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
10213
10214 if (eep_config.max_host_qng == 0) {
10215 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
10216 } else {
10217 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
10218 }
10219 }
10220
10221 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
10222 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
10223 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
10224
10225 if (eep_config.max_dvc_qng == 0) {
10226 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
10227 } else {
10228 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
10229 }
10230 }
10231
10232
10233
10234
10235
10236 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
10237 eep_config.max_dvc_qng = eep_config.max_host_qng;
10238 }
10239
10240
10241
10242
10243
10244 asc_dvc->max_host_qng = eep_config.max_host_qng;
10245 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
10246
10247
10248
10249
10250
10251
10252
10253
10254
10255 if (eep_config.termination == 0) {
10256 asc_dvc->cfg->termination = 0;
10257 } else {
10258
10259 if (eep_config.termination == 1) {
10260 asc_dvc->cfg->termination = TERM_CTL_SEL;
10261
10262
10263 } else if (eep_config.termination == 2) {
10264 asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
10265
10266
10267 } else if (eep_config.termination == 3) {
10268 asc_dvc->cfg->termination =
10269 TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
10270 } else {
10271
10272
10273
10274
10275 asc_dvc->cfg->termination = 0;
10276 warn_code |= ASC_WARN_EEPROM_TERMINATION;
10277 }
10278 }
10279
10280 return warn_code;
10281}
10282
10283
10284
10285
10286
10287
10288
10289
10290
10291
10292
10293
10294
10295static int AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
10296{
10297 AdvPortAddr iop_base;
10298 ushort warn_code;
10299 ADVEEP_38C0800_CONFIG eep_config;
10300 uchar tid, termination;
10301 ushort sdtr_speed = 0;
10302
10303 iop_base = asc_dvc->iop_base;
10304
10305 warn_code = 0;
10306
10307
10308
10309
10310
10311
10312 if (AdvGet38C0800EEPConfig(iop_base, &eep_config) !=
10313 eep_config.check_sum) {
10314 warn_code |= ASC_WARN_EEPROM_CHKSUM;
10315
10316
10317
10318
10319 memcpy(&eep_config, &Default_38C0800_EEPROM_Config,
10320 sizeof(ADVEEP_38C0800_CONFIG));
10321
10322
10323
10324
10325
10326 eep_config.serial_number_word3 =
10327 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
10328
10329 eep_config.serial_number_word2 =
10330 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
10331
10332 eep_config.serial_number_word1 =
10333 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
10334
10335 AdvSet38C0800EEPConfig(iop_base, &eep_config);
10336 }
10337
10338
10339
10340
10341
10342
10343 asc_dvc->wdtr_able = eep_config.wdtr_able;
10344 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
10345 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
10346 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
10347 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
10348 asc_dvc->tagqng_able = eep_config.tagqng_able;
10349 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
10350 asc_dvc->max_host_qng = eep_config.max_host_qng;
10351 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
10352 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
10353 asc_dvc->start_motor = eep_config.start_motor;
10354 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
10355 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
10356 asc_dvc->no_scam = eep_config.scam_tolerant;
10357 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
10358 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
10359 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
10360
10361
10362
10363
10364
10365 asc_dvc->sdtr_able = 0;
10366 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
10367 if (tid == 0) {
10368 sdtr_speed = asc_dvc->sdtr_speed1;
10369 } else if (tid == 4) {
10370 sdtr_speed = asc_dvc->sdtr_speed2;
10371 } else if (tid == 8) {
10372 sdtr_speed = asc_dvc->sdtr_speed3;
10373 } else if (tid == 12) {
10374 sdtr_speed = asc_dvc->sdtr_speed4;
10375 }
10376 if (sdtr_speed & ADV_MAX_TID) {
10377 asc_dvc->sdtr_able |= (1 << tid);
10378 }
10379 sdtr_speed >>= 4;
10380 }
10381
10382
10383
10384
10385
10386 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
10387 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
10388 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
10389
10390 if (eep_config.max_host_qng == 0) {
10391 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
10392 } else {
10393 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
10394 }
10395 }
10396
10397 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
10398 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
10399 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
10400
10401 if (eep_config.max_dvc_qng == 0) {
10402 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
10403 } else {
10404 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
10405 }
10406 }
10407
10408
10409
10410
10411
10412 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
10413 eep_config.max_dvc_qng = eep_config.max_host_qng;
10414 }
10415
10416
10417
10418
10419
10420 asc_dvc->max_host_qng = eep_config.max_host_qng;
10421 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
10422
10423
10424
10425
10426
10427
10428
10429
10430
10431 if (eep_config.termination_se == 0) {
10432 termination = 0;
10433 } else {
10434
10435 if (eep_config.termination_se == 1) {
10436 termination = 0;
10437
10438
10439 } else if (eep_config.termination_se == 2) {
10440 termination = TERM_SE_HI;
10441
10442
10443 } else if (eep_config.termination_se == 3) {
10444 termination = TERM_SE;
10445 } else {
10446
10447
10448
10449
10450 termination = 0;
10451 warn_code |= ASC_WARN_EEPROM_TERMINATION;
10452 }
10453 }
10454
10455 if (eep_config.termination_lvd == 0) {
10456 asc_dvc->cfg->termination = termination;
10457 } else {
10458
10459 if (eep_config.termination_lvd == 1) {
10460 asc_dvc->cfg->termination = termination;
10461
10462
10463 } else if (eep_config.termination_lvd == 2) {
10464 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
10465
10466
10467 } else if (eep_config.termination_lvd == 3) {
10468 asc_dvc->cfg->termination = termination | TERM_LVD;
10469 } else {
10470
10471
10472
10473
10474 asc_dvc->cfg->termination = termination;
10475 warn_code |= ASC_WARN_EEPROM_TERMINATION;
10476 }
10477 }
10478
10479 return warn_code;
10480}
10481
10482
10483
10484
10485
10486
10487
10488
10489
10490
10491
10492
10493
10494static int AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
10495{
10496 AdvPortAddr iop_base;
10497 ushort warn_code;
10498 ADVEEP_38C1600_CONFIG eep_config;
10499 uchar tid, termination;
10500 ushort sdtr_speed = 0;
10501
10502 iop_base = asc_dvc->iop_base;
10503
10504 warn_code = 0;
10505
10506
10507
10508
10509
10510
10511 if (AdvGet38C1600EEPConfig(iop_base, &eep_config) !=
10512 eep_config.check_sum) {
10513 struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc);
10514 warn_code |= ASC_WARN_EEPROM_CHKSUM;
10515
10516
10517
10518
10519 memcpy(&eep_config, &Default_38C1600_EEPROM_Config,
10520 sizeof(ADVEEP_38C1600_CONFIG));
10521
10522 if (PCI_FUNC(pdev->devfn) != 0) {
10523 u8 ints;
10524
10525
10526
10527
10528
10529 eep_config.cfg_lsw &= ~ADV_EEPROM_BIOS_ENABLE;
10530
10531
10532
10533
10534
10535
10536
10537
10538
10539
10540
10541
10542
10543 AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL, 0);
10544 ints = AdvReadByteRegister(iop_base, IOPB_GPIO_DATA);
10545 if ((ints & 0x01) == 0)
10546 eep_config.cfg_lsw &= ~ADV_EEPROM_INTAB;
10547 }
10548
10549
10550
10551
10552
10553 eep_config.serial_number_word3 =
10554 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
10555 eep_config.serial_number_word2 =
10556 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
10557 eep_config.serial_number_word1 =
10558 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
10559
10560 AdvSet38C1600EEPConfig(iop_base, &eep_config);
10561 }
10562
10563
10564
10565
10566
10567
10568
10569 asc_dvc->wdtr_able = eep_config.wdtr_able;
10570 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
10571 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
10572 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
10573 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
10574 asc_dvc->ppr_able = 0;
10575 asc_dvc->tagqng_able = eep_config.tagqng_able;
10576 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
10577 asc_dvc->max_host_qng = eep_config.max_host_qng;
10578 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
10579 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
10580 asc_dvc->start_motor = eep_config.start_motor;
10581 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
10582 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
10583 asc_dvc->no_scam = eep_config.scam_tolerant;
10584
10585
10586
10587
10588
10589 asc_dvc->sdtr_able = 0;
10590 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
10591 if (tid == 0) {
10592 sdtr_speed = asc_dvc->sdtr_speed1;
10593 } else if (tid == 4) {
10594 sdtr_speed = asc_dvc->sdtr_speed2;
10595 } else if (tid == 8) {
10596 sdtr_speed = asc_dvc->sdtr_speed3;
10597 } else if (tid == 12) {
10598 sdtr_speed = asc_dvc->sdtr_speed4;
10599 }
10600 if (sdtr_speed & ASC_MAX_TID) {
10601 asc_dvc->sdtr_able |= (1 << tid);
10602 }
10603 sdtr_speed >>= 4;
10604 }
10605
10606
10607
10608
10609
10610 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
10611 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
10612 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
10613
10614 if (eep_config.max_host_qng == 0) {
10615 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
10616 } else {
10617 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
10618 }
10619 }
10620
10621 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
10622 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
10623 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
10624
10625 if (eep_config.max_dvc_qng == 0) {
10626 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
10627 } else {
10628 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
10629 }
10630 }
10631
10632
10633
10634
10635
10636 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
10637 eep_config.max_dvc_qng = eep_config.max_host_qng;
10638 }
10639
10640
10641
10642
10643
10644 asc_dvc->max_host_qng = eep_config.max_host_qng;
10645 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
10646
10647
10648
10649
10650
10651
10652
10653
10654
10655 if (eep_config.termination_se == 0) {
10656 termination = 0;
10657 } else {
10658
10659 if (eep_config.termination_se == 1) {
10660 termination = 0;
10661
10662
10663 } else if (eep_config.termination_se == 2) {
10664 termination = TERM_SE_HI;
10665
10666
10667 } else if (eep_config.termination_se == 3) {
10668 termination = TERM_SE;
10669 } else {
10670
10671
10672
10673
10674 termination = 0;
10675 warn_code |= ASC_WARN_EEPROM_TERMINATION;
10676 }
10677 }
10678
10679 if (eep_config.termination_lvd == 0) {
10680 asc_dvc->cfg->termination = termination;
10681 } else {
10682
10683 if (eep_config.termination_lvd == 1) {
10684 asc_dvc->cfg->termination = termination;
10685
10686
10687 } else if (eep_config.termination_lvd == 2) {
10688 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
10689
10690
10691 } else if (eep_config.termination_lvd == 3) {
10692 asc_dvc->cfg->termination = termination | TERM_LVD;
10693 } else {
10694
10695
10696
10697
10698 asc_dvc->cfg->termination = termination;
10699 warn_code |= ASC_WARN_EEPROM_TERMINATION;
10700 }
10701 }
10702
10703 return warn_code;
10704}
10705
10706
10707
10708
10709
10710
10711
10712
10713
10714static int AdvInitGetConfig(struct pci_dev *pdev, struct Scsi_Host *shost)
10715{
10716 struct asc_board *board = shost_priv(shost);
10717 ADV_DVC_VAR *asc_dvc = &board->dvc_var.adv_dvc_var;
10718 unsigned short warn_code = 0;
10719 AdvPortAddr iop_base = asc_dvc->iop_base;
10720 u16 cmd;
10721 int status;
10722
10723 asc_dvc->err_code = 0;
10724
10725
10726
10727
10728
10729
10730
10731 asc_dvc->cfg->control_flag = 0;
10732 pci_read_config_word(pdev, PCI_COMMAND, &cmd);
10733 if ((cmd & PCI_COMMAND_PARITY) == 0)
10734 asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
10735
10736 asc_dvc->cfg->chip_version =
10737 AdvGetChipVersion(iop_base, asc_dvc->bus_type);
10738
10739 ASC_DBG(1, "iopb_chip_id_1: 0x%x 0x%x\n",
10740 (ushort)AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
10741 (ushort)ADV_CHIP_ID_BYTE);
10742
10743 ASC_DBG(1, "iopw_chip_id_0: 0x%x 0x%x\n",
10744 (ushort)AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
10745 (ushort)ADV_CHIP_ID_WORD);
10746
10747
10748
10749
10750 if (AdvFindSignature(iop_base) == 0) {
10751 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10752 return ADV_ERROR;
10753 } else {
10754
10755
10756
10757 if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
10758 asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
10759 asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
10760 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
10761 return ADV_ERROR;
10762 }
10763
10764
10765
10766
10767 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
10768 ADV_CTRL_REG_CMD_RESET);
10769 mdelay(100);
10770 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
10771 ADV_CTRL_REG_CMD_WR_IO_REG);
10772
10773 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
10774 status = AdvInitFrom38C1600EEP(asc_dvc);
10775 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
10776 status = AdvInitFrom38C0800EEP(asc_dvc);
10777 } else {
10778 status = AdvInitFrom3550EEP(asc_dvc);
10779 }
10780 warn_code |= status;
10781 }
10782
10783 if (warn_code != 0)
10784 shost_printk(KERN_WARNING, shost, "warning: 0x%x\n", warn_code);
10785
10786 if (asc_dvc->err_code)
10787 shost_printk(KERN_ERR, shost, "error code 0x%x\n",
10788 asc_dvc->err_code);
10789
10790 return asc_dvc->err_code;
10791}
10792#endif
10793
10794static struct scsi_host_template advansys_template = {
10795 .proc_name = DRV_NAME,
10796#ifdef CONFIG_PROC_FS
10797 .show_info = advansys_show_info,
10798#endif
10799 .name = DRV_NAME,
10800 .info = advansys_info,
10801 .queuecommand = advansys_queuecommand,
10802 .eh_host_reset_handler = advansys_reset,
10803 .bios_param = advansys_biosparam,
10804 .slave_configure = advansys_slave_configure,
10805
10806
10807
10808
10809
10810 .unchecked_isa_dma = true,
10811
10812
10813
10814
10815
10816
10817
10818 .use_clustering = ENABLE_CLUSTERING,
10819};
10820
10821static int advansys_wide_init_chip(struct Scsi_Host *shost)
10822{
10823 struct asc_board *board = shost_priv(shost);
10824 struct adv_dvc_var *adv_dvc = &board->dvc_var.adv_dvc_var;
10825 size_t sgblk_pool_size;
10826 int warn_code, err_code;
10827
10828
10829
10830
10831
10832 adv_dvc->carrier = dma_alloc_coherent(board->dev,
10833 ADV_CARRIER_BUFSIZE, &adv_dvc->carrier_addr, GFP_KERNEL);
10834 ASC_DBG(1, "carrier 0x%p\n", adv_dvc->carrier);
10835
10836 if (!adv_dvc->carrier)
10837 goto kmalloc_failed;
10838
10839
10840
10841
10842
10843
10844 board->adv_reqp_size = adv_dvc->max_host_qng * sizeof(adv_req_t);
10845 if (board->adv_reqp_size & 0x1f) {
10846 ASC_DBG(1, "unaligned reqp %lu bytes\n", sizeof(adv_req_t));
10847 board->adv_reqp_size = ADV_32BALIGN(board->adv_reqp_size);
10848 }
10849 board->adv_reqp = dma_alloc_coherent(board->dev, board->adv_reqp_size,
10850 &board->adv_reqp_addr, GFP_KERNEL);
10851
10852 if (!board->adv_reqp)
10853 goto kmalloc_failed;
10854
10855 ASC_DBG(1, "reqp 0x%p, req_cnt %d, bytes %lu\n", board->adv_reqp,
10856 adv_dvc->max_host_qng, board->adv_reqp_size);
10857
10858
10859
10860
10861
10862 sgblk_pool_size = sizeof(adv_sgblk_t) * ADV_TOT_SG_BLOCK;
10863 board->adv_sgblk_pool = dma_pool_create("adv_sgblk", board->dev,
10864 sgblk_pool_size, 32, 0);
10865
10866 ASC_DBG(1, "sg_cnt %d * %lu = %lu bytes\n", ADV_TOT_SG_BLOCK,
10867 sizeof(adv_sgblk_t), sgblk_pool_size);
10868
10869 if (!board->adv_sgblk_pool)
10870 goto kmalloc_failed;
10871
10872 if (adv_dvc->chip_type == ADV_CHIP_ASC3550) {
10873 ASC_DBG(2, "AdvInitAsc3550Driver()\n");
10874 warn_code = AdvInitAsc3550Driver(adv_dvc);
10875 } else if (adv_dvc->chip_type == ADV_CHIP_ASC38C0800) {
10876 ASC_DBG(2, "AdvInitAsc38C0800Driver()\n");
10877 warn_code = AdvInitAsc38C0800Driver(adv_dvc);
10878 } else {
10879 ASC_DBG(2, "AdvInitAsc38C1600Driver()\n");
10880 warn_code = AdvInitAsc38C1600Driver(adv_dvc);
10881 }
10882 err_code = adv_dvc->err_code;
10883
10884 if (warn_code || err_code) {
10885 shost_printk(KERN_WARNING, shost, "error: warn 0x%x, error "
10886 "0x%x\n", warn_code, err_code);
10887 }
10888
10889 goto exit;
10890
10891 kmalloc_failed:
10892 shost_printk(KERN_ERR, shost, "error: kmalloc() failed\n");
10893 err_code = ADV_ERROR;
10894 exit:
10895 return err_code;
10896}
10897
10898static void advansys_wide_free_mem(struct asc_board *board)
10899{
10900 struct adv_dvc_var *adv_dvc = &board->dvc_var.adv_dvc_var;
10901
10902 if (adv_dvc->carrier) {
10903 dma_free_coherent(board->dev, ADV_CARRIER_BUFSIZE,
10904 adv_dvc->carrier, adv_dvc->carrier_addr);
10905 adv_dvc->carrier = NULL;
10906 }
10907 if (board->adv_reqp) {
10908 dma_free_coherent(board->dev, board->adv_reqp_size,
10909 board->adv_reqp, board->adv_reqp_addr);
10910 board->adv_reqp = NULL;
10911 }
10912 if (board->adv_sgblk_pool) {
10913 dma_pool_destroy(board->adv_sgblk_pool);
10914 board->adv_sgblk_pool = NULL;
10915 }
10916}
10917
10918static int advansys_board_found(struct Scsi_Host *shost, unsigned int iop,
10919 int bus_type)
10920{
10921 struct pci_dev *pdev;
10922 struct asc_board *boardp = shost_priv(shost);
10923 ASC_DVC_VAR *asc_dvc_varp = NULL;
10924 ADV_DVC_VAR *adv_dvc_varp = NULL;
10925 int share_irq, warn_code, ret;
10926
10927 pdev = (bus_type == ASC_IS_PCI) ? to_pci_dev(boardp->dev) : NULL;
10928
10929 if (ASC_NARROW_BOARD(boardp)) {
10930 ASC_DBG(1, "narrow board\n");
10931 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
10932 asc_dvc_varp->bus_type = bus_type;
10933 asc_dvc_varp->drv_ptr = boardp;
10934 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
10935 asc_dvc_varp->iop_base = iop;
10936 } else {
10937#ifdef CONFIG_PCI
10938 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
10939 adv_dvc_varp->drv_ptr = boardp;
10940 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
10941 if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) {
10942 ASC_DBG(1, "wide board ASC-3550\n");
10943 adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
10944 } else if (pdev->device == PCI_DEVICE_ID_38C0800_REV1) {
10945 ASC_DBG(1, "wide board ASC-38C0800\n");
10946 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
10947 } else {
10948 ASC_DBG(1, "wide board ASC-38C1600\n");
10949 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
10950 }
10951
10952 boardp->asc_n_io_port = pci_resource_len(pdev, 1);
10953 boardp->ioremap_addr = pci_ioremap_bar(pdev, 1);
10954 if (!boardp->ioremap_addr) {
10955 shost_printk(KERN_ERR, shost, "ioremap(%lx, %d) "
10956 "returned NULL\n",
10957 (long)pci_resource_start(pdev, 1),
10958 boardp->asc_n_io_port);
10959 ret = -ENODEV;
10960 goto err_shost;
10961 }
10962 adv_dvc_varp->iop_base = (AdvPortAddr)boardp->ioremap_addr;
10963 ASC_DBG(1, "iop_base: 0x%p\n", adv_dvc_varp->iop_base);
10964
10965
10966
10967
10968
10969
10970 boardp->ioport = iop;
10971
10972 ASC_DBG(1, "iopb_chip_id_1 0x%x, iopw_chip_id_0 0x%x\n",
10973 (ushort)inp(iop + 1), (ushort)inpw(iop));
10974#endif
10975 }
10976
10977 if (ASC_NARROW_BOARD(boardp)) {
10978
10979
10980
10981
10982 switch (asc_dvc_varp->bus_type) {
10983#ifdef CONFIG_ISA
10984 case ASC_IS_ISA:
10985 shost->unchecked_isa_dma = true;
10986 share_irq = 0;
10987 break;
10988 case ASC_IS_VL:
10989 shost->unchecked_isa_dma = false;
10990 share_irq = 0;
10991 break;
10992 case ASC_IS_EISA:
10993 shost->unchecked_isa_dma = false;
10994 share_irq = IRQF_SHARED;
10995 break;
10996#endif
10997#ifdef CONFIG_PCI
10998 case ASC_IS_PCI:
10999 shost->unchecked_isa_dma = false;
11000 share_irq = IRQF_SHARED;
11001 break;
11002#endif
11003 default:
11004 shost_printk(KERN_ERR, shost, "unknown adapter type: "
11005 "%d\n", asc_dvc_varp->bus_type);
11006 shost->unchecked_isa_dma = false;
11007 share_irq = 0;
11008 break;
11009 }
11010
11011
11012
11013
11014
11015
11016
11017 ASC_DBG(2, "AscInitGetConfig()\n");
11018 ret = AscInitGetConfig(shost) ? -ENODEV : 0;
11019 } else {
11020#ifdef CONFIG_PCI
11021
11022
11023
11024
11025 shost->unchecked_isa_dma = false;
11026 share_irq = IRQF_SHARED;
11027 ASC_DBG(2, "AdvInitGetConfig()\n");
11028
11029 ret = AdvInitGetConfig(pdev, shost) ? -ENODEV : 0;
11030#else
11031 share_irq = 0;
11032 ret = -ENODEV;
11033#endif
11034 }
11035
11036 if (ret)
11037 goto err_unmap;
11038
11039
11040
11041
11042
11043 if (ASC_NARROW_BOARD(boardp)) {
11044
11045 ASCEEP_CONFIG *ep;
11046
11047
11048
11049
11050 boardp->init_tidmask |=
11051 ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
11052
11053
11054
11055
11056 ep = &boardp->eep_config.asc_eep;
11057
11058 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
11059 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
11060 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
11061 ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
11062 ep->start_motor = asc_dvc_varp->start_motor;
11063 ep->cntl = asc_dvc_varp->dvc_cntl;
11064 ep->no_scam = asc_dvc_varp->no_scam;
11065 ep->max_total_qng = asc_dvc_varp->max_total_qng;
11066 ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
11067
11068 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
11069 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
11070 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
11071 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
11072 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
11073 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
11074 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
11075
11076
11077
11078
11079 ASC_DBG(2, "AscInitSetConfig()\n");
11080 ret = AscInitSetConfig(pdev, shost) ? -ENODEV : 0;
11081 if (ret)
11082 goto err_unmap;
11083 } else {
11084 ADVEEP_3550_CONFIG *ep_3550;
11085 ADVEEP_38C0800_CONFIG *ep_38C0800;
11086 ADVEEP_38C1600_CONFIG *ep_38C1600;
11087
11088
11089
11090
11091 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
11092 ep_3550 = &boardp->eep_config.adv_3550_eep;
11093
11094 ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
11095 ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
11096 ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
11097 ep_3550->termination = adv_dvc_varp->cfg->termination;
11098 ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
11099 ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
11100 ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
11101 ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
11102 ep_3550->ultra_able = adv_dvc_varp->ultra_able;
11103 ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
11104 ep_3550->start_motor = adv_dvc_varp->start_motor;
11105 ep_3550->scsi_reset_delay =
11106 adv_dvc_varp->scsi_reset_wait;
11107 ep_3550->serial_number_word1 =
11108 adv_dvc_varp->cfg->serial1;
11109 ep_3550->serial_number_word2 =
11110 adv_dvc_varp->cfg->serial2;
11111 ep_3550->serial_number_word3 =
11112 adv_dvc_varp->cfg->serial3;
11113 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
11114 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
11115
11116 ep_38C0800->adapter_scsi_id =
11117 adv_dvc_varp->chip_scsi_id;
11118 ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
11119 ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
11120 ep_38C0800->termination_lvd =
11121 adv_dvc_varp->cfg->termination;
11122 ep_38C0800->disc_enable =
11123 adv_dvc_varp->cfg->disc_enable;
11124 ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
11125 ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
11126 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
11127 ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
11128 ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
11129 ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
11130 ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
11131 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
11132 ep_38C0800->start_motor = adv_dvc_varp->start_motor;
11133 ep_38C0800->scsi_reset_delay =
11134 adv_dvc_varp->scsi_reset_wait;
11135 ep_38C0800->serial_number_word1 =
11136 adv_dvc_varp->cfg->serial1;
11137 ep_38C0800->serial_number_word2 =
11138 adv_dvc_varp->cfg->serial2;
11139 ep_38C0800->serial_number_word3 =
11140 adv_dvc_varp->cfg->serial3;
11141 } else {
11142 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
11143
11144 ep_38C1600->adapter_scsi_id =
11145 adv_dvc_varp->chip_scsi_id;
11146 ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
11147 ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
11148 ep_38C1600->termination_lvd =
11149 adv_dvc_varp->cfg->termination;
11150 ep_38C1600->disc_enable =
11151 adv_dvc_varp->cfg->disc_enable;
11152 ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
11153 ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
11154 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
11155 ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
11156 ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
11157 ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
11158 ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
11159 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
11160 ep_38C1600->start_motor = adv_dvc_varp->start_motor;
11161 ep_38C1600->scsi_reset_delay =
11162 adv_dvc_varp->scsi_reset_wait;
11163 ep_38C1600->serial_number_word1 =
11164 adv_dvc_varp->cfg->serial1;
11165 ep_38C1600->serial_number_word2 =
11166 adv_dvc_varp->cfg->serial2;
11167 ep_38C1600->serial_number_word3 =
11168 adv_dvc_varp->cfg->serial3;
11169 }
11170
11171
11172
11173
11174 boardp->init_tidmask |=
11175 ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
11176 }
11177
11178
11179
11180
11181
11182
11183 shost->max_channel = 0;
11184 if (ASC_NARROW_BOARD(boardp)) {
11185 shost->max_id = ASC_MAX_TID + 1;
11186 shost->max_lun = ASC_MAX_LUN + 1;
11187 shost->max_cmd_len = ASC_MAX_CDB_LEN;
11188
11189 shost->io_port = asc_dvc_varp->iop_base;
11190 boardp->asc_n_io_port = ASC_IOADR_GAP;
11191 shost->this_id = asc_dvc_varp->cfg->chip_scsi_id;
11192
11193
11194 shost->can_queue = asc_dvc_varp->max_total_qng;
11195 } else {
11196 shost->max_id = ADV_MAX_TID + 1;
11197 shost->max_lun = ADV_MAX_LUN + 1;
11198 shost->max_cmd_len = ADV_MAX_CDB_LEN;
11199
11200
11201
11202
11203
11204
11205
11206 shost->io_port = iop;
11207
11208 shost->this_id = adv_dvc_varp->chip_scsi_id;
11209
11210
11211 shost->can_queue = adv_dvc_varp->max_host_qng;
11212 }
11213
11214
11215
11216
11217
11218 if (ASC_NARROW_BOARD(boardp)) {
11219
11220
11221
11222
11223
11224
11225 shost->sg_tablesize =
11226 (((asc_dvc_varp->max_total_qng - 2) / 2) *
11227 ASC_SG_LIST_PER_Q) + 1;
11228 } else {
11229 shost->sg_tablesize = ADV_MAX_SG_LIST;
11230 }
11231
11232
11233
11234
11235
11236
11237
11238 if (shost->sg_tablesize > SG_ALL) {
11239 shost->sg_tablesize = SG_ALL;
11240 }
11241
11242 ASC_DBG(1, "sg_tablesize: %d\n", shost->sg_tablesize);
11243
11244
11245 if (ASC_NARROW_BOARD(boardp)) {
11246 shost->base = AscGetChipBiosAddress(asc_dvc_varp->iop_base,
11247 asc_dvc_varp->bus_type);
11248 } else {
11249
11250
11251
11252
11253 AdvReadWordLram(adv_dvc_varp->iop_base,
11254 BIOS_SIGNATURE, boardp->bios_signature);
11255 AdvReadWordLram(adv_dvc_varp->iop_base,
11256 BIOS_VERSION, boardp->bios_version);
11257 AdvReadWordLram(adv_dvc_varp->iop_base,
11258 BIOS_CODESEG, boardp->bios_codeseg);
11259 AdvReadWordLram(adv_dvc_varp->iop_base,
11260 BIOS_CODELEN, boardp->bios_codelen);
11261
11262 ASC_DBG(1, "bios_signature 0x%x, bios_version 0x%x\n",
11263 boardp->bios_signature, boardp->bios_version);
11264
11265 ASC_DBG(1, "bios_codeseg 0x%x, bios_codelen 0x%x\n",
11266 boardp->bios_codeseg, boardp->bios_codelen);
11267
11268
11269
11270
11271
11272 if (boardp->bios_signature == 0x55AA) {
11273
11274
11275
11276
11277 shost->base = ((ulong)boardp->bios_codeseg << 4);
11278 } else {
11279 shost->base = 0;
11280 }
11281 }
11282
11283
11284
11285
11286
11287
11288 shost->dma_channel = NO_ISA_DMA;
11289#ifdef CONFIG_ISA
11290 if (ASC_NARROW_BOARD(boardp)) {
11291
11292 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
11293 shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
11294 ret = request_dma(shost->dma_channel, DRV_NAME);
11295 if (ret) {
11296 shost_printk(KERN_ERR, shost, "request_dma() "
11297 "%d failed %d\n",
11298 shost->dma_channel, ret);
11299 goto err_unmap;
11300 }
11301 AscEnableIsaDma(shost->dma_channel);
11302 }
11303 }
11304#endif
11305
11306
11307 ASC_DBG(2, "request_irq(%d, %p)\n", boardp->irq, shost);
11308
11309 ret = request_irq(boardp->irq, advansys_interrupt, share_irq,
11310 DRV_NAME, shost);
11311
11312 if (ret) {
11313 if (ret == -EBUSY) {
11314 shost_printk(KERN_ERR, shost, "request_irq(): IRQ 0x%x "
11315 "already in use\n", boardp->irq);
11316 } else if (ret == -EINVAL) {
11317 shost_printk(KERN_ERR, shost, "request_irq(): IRQ 0x%x "
11318 "not valid\n", boardp->irq);
11319 } else {
11320 shost_printk(KERN_ERR, shost, "request_irq(): IRQ 0x%x "
11321 "failed with %d\n", boardp->irq, ret);
11322 }
11323 goto err_free_dma;
11324 }
11325
11326
11327
11328
11329 if (ASC_NARROW_BOARD(boardp)) {
11330 ASC_DBG(2, "AscInitAsc1000Driver()\n");
11331
11332 asc_dvc_varp->overrun_buf = kzalloc(ASC_OVERRUN_BSIZE, GFP_KERNEL);
11333 if (!asc_dvc_varp->overrun_buf) {
11334 ret = -ENOMEM;
11335 goto err_free_irq;
11336 }
11337 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
11338
11339 if (warn_code || asc_dvc_varp->err_code) {
11340 shost_printk(KERN_ERR, shost, "error: init_state 0x%x, "
11341 "warn 0x%x, error 0x%x\n",
11342 asc_dvc_varp->init_state, warn_code,
11343 asc_dvc_varp->err_code);
11344 if (!asc_dvc_varp->overrun_dma) {
11345 ret = -ENODEV;
11346 goto err_free_mem;
11347 }
11348 }
11349 } else {
11350 if (advansys_wide_init_chip(shost)) {
11351 ret = -ENODEV;
11352 goto err_free_mem;
11353 }
11354 }
11355
11356 ASC_DBG_PRT_SCSI_HOST(2, shost);
11357
11358 ret = scsi_add_host(shost, boardp->dev);
11359 if (ret)
11360 goto err_free_mem;
11361
11362 scsi_scan_host(shost);
11363 return 0;
11364
11365 err_free_mem:
11366 if (ASC_NARROW_BOARD(boardp)) {
11367 if (asc_dvc_varp->overrun_dma)
11368 dma_unmap_single(boardp->dev, asc_dvc_varp->overrun_dma,
11369 ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE);
11370 kfree(asc_dvc_varp->overrun_buf);
11371 } else
11372 advansys_wide_free_mem(boardp);
11373 err_free_irq:
11374 free_irq(boardp->irq, shost);
11375 err_free_dma:
11376#ifdef CONFIG_ISA
11377 if (shost->dma_channel != NO_ISA_DMA)
11378 free_dma(shost->dma_channel);
11379#endif
11380 err_unmap:
11381 if (boardp->ioremap_addr)
11382 iounmap(boardp->ioremap_addr);
11383#ifdef CONFIG_PCI
11384 err_shost:
11385#endif
11386 return ret;
11387}
11388
11389
11390
11391
11392
11393
11394static int advansys_release(struct Scsi_Host *shost)
11395{
11396 struct asc_board *board = shost_priv(shost);
11397 ASC_DBG(1, "begin\n");
11398 scsi_remove_host(shost);
11399 free_irq(board->irq, shost);
11400#ifdef CONFIG_ISA
11401 if (shost->dma_channel != NO_ISA_DMA) {
11402 ASC_DBG(1, "free_dma()\n");
11403 free_dma(shost->dma_channel);
11404 }
11405#endif
11406 if (ASC_NARROW_BOARD(board)) {
11407 dma_unmap_single(board->dev,
11408 board->dvc_var.asc_dvc_var.overrun_dma,
11409 ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE);
11410 kfree(board->dvc_var.asc_dvc_var.overrun_buf);
11411 } else {
11412 iounmap(board->ioremap_addr);
11413 advansys_wide_free_mem(board);
11414 }
11415 scsi_host_put(shost);
11416 ASC_DBG(1, "end\n");
11417 return 0;
11418}
11419
11420#define ASC_IOADR_TABLE_MAX_IX 11
11421
11422static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] = {
11423 0x100, 0x0110, 0x120, 0x0130, 0x140, 0x0150, 0x0190,
11424 0x0210, 0x0230, 0x0250, 0x0330
11425};
11426
11427
11428
11429
11430
11431
11432
11433
11434static unsigned int advansys_isa_irq_no(PortAddr iop_base)
11435{
11436 unsigned short cfg_lsw = AscGetChipCfgLsw(iop_base);
11437 unsigned int chip_irq = ((cfg_lsw >> 2) & 0x03) + 10;
11438 if (chip_irq == 13)
11439 chip_irq = 15;
11440 return chip_irq;
11441}
11442
11443static int advansys_isa_probe(struct device *dev, unsigned int id)
11444{
11445 int err = -ENODEV;
11446 PortAddr iop_base = _asc_def_iop_base[id];
11447 struct Scsi_Host *shost;
11448 struct asc_board *board;
11449
11450 if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) {
11451 ASC_DBG(1, "I/O port 0x%x busy\n", iop_base);
11452 return -ENODEV;
11453 }
11454 ASC_DBG(1, "probing I/O port 0x%x\n", iop_base);
11455 if (!AscFindSignature(iop_base))
11456 goto release_region;
11457 if (!(AscGetChipVersion(iop_base, ASC_IS_ISA) & ASC_CHIP_VER_ISA_BIT))
11458 goto release_region;
11459
11460 err = -ENOMEM;
11461 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
11462 if (!shost)
11463 goto release_region;
11464
11465 board = shost_priv(shost);
11466 board->irq = advansys_isa_irq_no(iop_base);
11467 board->dev = dev;
11468 board->shost = shost;
11469
11470 err = advansys_board_found(shost, iop_base, ASC_IS_ISA);
11471 if (err)
11472 goto free_host;
11473
11474 dev_set_drvdata(dev, shost);
11475 return 0;
11476
11477 free_host:
11478 scsi_host_put(shost);
11479 release_region:
11480 release_region(iop_base, ASC_IOADR_GAP);
11481 return err;
11482}
11483
11484static int advansys_isa_remove(struct device *dev, unsigned int id)
11485{
11486 int ioport = _asc_def_iop_base[id];
11487 advansys_release(dev_get_drvdata(dev));
11488 release_region(ioport, ASC_IOADR_GAP);
11489 return 0;
11490}
11491
11492static struct isa_driver advansys_isa_driver = {
11493 .probe = advansys_isa_probe,
11494 .remove = advansys_isa_remove,
11495 .driver = {
11496 .owner = THIS_MODULE,
11497 .name = DRV_NAME,
11498 },
11499};
11500
11501
11502
11503
11504
11505
11506
11507
11508
11509
11510
11511
11512static unsigned int advansys_vlb_irq_no(PortAddr iop_base)
11513{
11514 unsigned short cfg_lsw = AscGetChipCfgLsw(iop_base);
11515 unsigned int chip_irq = ((cfg_lsw >> 2) & 0x07) + 9;
11516 if ((chip_irq < 10) || (chip_irq == 13) || (chip_irq > 15))
11517 return 0;
11518 return chip_irq;
11519}
11520
11521static int advansys_vlb_probe(struct device *dev, unsigned int id)
11522{
11523 int err = -ENODEV;
11524 PortAddr iop_base = _asc_def_iop_base[id];
11525 struct Scsi_Host *shost;
11526 struct asc_board *board;
11527
11528 if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) {
11529 ASC_DBG(1, "I/O port 0x%x busy\n", iop_base);
11530 return -ENODEV;
11531 }
11532 ASC_DBG(1, "probing I/O port 0x%x\n", iop_base);
11533 if (!AscFindSignature(iop_base))
11534 goto release_region;
11535
11536
11537
11538
11539
11540 if (AscGetChipVersion(iop_base, ASC_IS_VL) > ASC_CHIP_MAX_VER_VL)
11541 goto release_region;
11542
11543 err = -ENOMEM;
11544 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
11545 if (!shost)
11546 goto release_region;
11547
11548 board = shost_priv(shost);
11549 board->irq = advansys_vlb_irq_no(iop_base);
11550 board->dev = dev;
11551 board->shost = shost;
11552
11553 err = advansys_board_found(shost, iop_base, ASC_IS_VL);
11554 if (err)
11555 goto free_host;
11556
11557 dev_set_drvdata(dev, shost);
11558 return 0;
11559
11560 free_host:
11561 scsi_host_put(shost);
11562 release_region:
11563 release_region(iop_base, ASC_IOADR_GAP);
11564 return -ENODEV;
11565}
11566
11567static struct isa_driver advansys_vlb_driver = {
11568 .probe = advansys_vlb_probe,
11569 .remove = advansys_isa_remove,
11570 .driver = {
11571 .owner = THIS_MODULE,
11572 .name = "advansys_vlb",
11573 },
11574};
11575
11576static struct eisa_device_id advansys_eisa_table[] = {
11577 { "ABP7401" },
11578 { "ABP7501" },
11579 { "" }
11580};
11581
11582MODULE_DEVICE_TABLE(eisa, advansys_eisa_table);
11583
11584
11585
11586
11587
11588struct eisa_scsi_data {
11589 struct Scsi_Host *host[2];
11590};
11591
11592
11593
11594
11595
11596
11597
11598
11599
11600
11601
11602
11603static unsigned int advansys_eisa_irq_no(struct eisa_device *edev)
11604{
11605 unsigned short cfg_lsw = inw(edev->base_addr + 0xc86);
11606 unsigned int chip_irq = ((cfg_lsw >> 8) & 0x07) + 10;
11607 if ((chip_irq == 13) || (chip_irq > 15))
11608 return 0;
11609 return chip_irq;
11610}
11611
11612static int advansys_eisa_probe(struct device *dev)
11613{
11614 int i, ioport, irq = 0;
11615 int err;
11616 struct eisa_device *edev = to_eisa_device(dev);
11617 struct eisa_scsi_data *data;
11618
11619 err = -ENOMEM;
11620 data = kzalloc(sizeof(*data), GFP_KERNEL);
11621 if (!data)
11622 goto fail;
11623 ioport = edev->base_addr + 0xc30;
11624
11625 err = -ENODEV;
11626 for (i = 0; i < 2; i++, ioport += 0x20) {
11627 struct asc_board *board;
11628 struct Scsi_Host *shost;
11629 if (!request_region(ioport, ASC_IOADR_GAP, DRV_NAME)) {
11630 printk(KERN_WARNING "Region %x-%x busy\n", ioport,
11631 ioport + ASC_IOADR_GAP - 1);
11632 continue;
11633 }
11634 if (!AscFindSignature(ioport)) {
11635 release_region(ioport, ASC_IOADR_GAP);
11636 continue;
11637 }
11638
11639
11640
11641
11642
11643
11644
11645
11646 inw(ioport + 4);
11647
11648 if (!irq)
11649 irq = advansys_eisa_irq_no(edev);
11650
11651 err = -ENOMEM;
11652 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
11653 if (!shost)
11654 goto release_region;
11655
11656 board = shost_priv(shost);
11657 board->irq = irq;
11658 board->dev = dev;
11659 board->shost = shost;
11660
11661 err = advansys_board_found(shost, ioport, ASC_IS_EISA);
11662 if (!err) {
11663 data->host[i] = shost;
11664 continue;
11665 }
11666
11667 scsi_host_put(shost);
11668 release_region:
11669 release_region(ioport, ASC_IOADR_GAP);
11670 break;
11671 }
11672
11673 if (err)
11674 goto free_data;
11675 dev_set_drvdata(dev, data);
11676 return 0;
11677
11678 free_data:
11679 kfree(data->host[0]);
11680 kfree(data->host[1]);
11681 kfree(data);
11682 fail:
11683 return err;
11684}
11685
11686static int advansys_eisa_remove(struct device *dev)
11687{
11688 int i;
11689 struct eisa_scsi_data *data = dev_get_drvdata(dev);
11690
11691 for (i = 0; i < 2; i++) {
11692 int ioport;
11693 struct Scsi_Host *shost = data->host[i];
11694 if (!shost)
11695 continue;
11696 ioport = shost->io_port;
11697 advansys_release(shost);
11698 release_region(ioport, ASC_IOADR_GAP);
11699 }
11700
11701 kfree(data);
11702 return 0;
11703}
11704
11705static struct eisa_driver advansys_eisa_driver = {
11706 .id_table = advansys_eisa_table,
11707 .driver = {
11708 .name = DRV_NAME,
11709 .probe = advansys_eisa_probe,
11710 .remove = advansys_eisa_remove,
11711 }
11712};
11713
11714
11715static struct pci_device_id advansys_pci_tbl[] = {
11716 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A,
11717 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
11718 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940,
11719 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
11720 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940U,
11721 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
11722 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940UW,
11723 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
11724 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C0800_REV1,
11725 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
11726 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C1600_REV1,
11727 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
11728 {}
11729};
11730
11731MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);
11732
11733static void advansys_set_latency(struct pci_dev *pdev)
11734{
11735 if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
11736 (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
11737 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0);
11738 } else {
11739 u8 latency;
11740 pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency);
11741 if (latency < 0x20)
11742 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x20);
11743 }
11744}
11745
11746static int advansys_pci_probe(struct pci_dev *pdev,
11747 const struct pci_device_id *ent)
11748{
11749 int err, ioport;
11750 struct Scsi_Host *shost;
11751 struct asc_board *board;
11752
11753 err = pci_enable_device(pdev);
11754 if (err)
11755 goto fail;
11756 err = pci_request_regions(pdev, DRV_NAME);
11757 if (err)
11758 goto disable_device;
11759 pci_set_master(pdev);
11760 advansys_set_latency(pdev);
11761
11762 err = -ENODEV;
11763 if (pci_resource_len(pdev, 0) == 0)
11764 goto release_region;
11765
11766 ioport = pci_resource_start(pdev, 0);
11767
11768 err = -ENOMEM;
11769 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
11770 if (!shost)
11771 goto release_region;
11772
11773 board = shost_priv(shost);
11774 board->irq = pdev->irq;
11775 board->dev = &pdev->dev;
11776 board->shost = shost;
11777
11778 if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW ||
11779 pdev->device == PCI_DEVICE_ID_38C0800_REV1 ||
11780 pdev->device == PCI_DEVICE_ID_38C1600_REV1) {
11781 board->flags |= ASC_IS_WIDE_BOARD;
11782 }
11783
11784 err = advansys_board_found(shost, ioport, ASC_IS_PCI);
11785 if (err)
11786 goto free_host;
11787
11788 pci_set_drvdata(pdev, shost);
11789 return 0;
11790
11791 free_host:
11792 scsi_host_put(shost);
11793 release_region:
11794 pci_release_regions(pdev);
11795 disable_device:
11796 pci_disable_device(pdev);
11797 fail:
11798 return err;
11799}
11800
11801static void advansys_pci_remove(struct pci_dev *pdev)
11802{
11803 advansys_release(pci_get_drvdata(pdev));
11804 pci_release_regions(pdev);
11805 pci_disable_device(pdev);
11806}
11807
11808static struct pci_driver advansys_pci_driver = {
11809 .name = DRV_NAME,
11810 .id_table = advansys_pci_tbl,
11811 .probe = advansys_pci_probe,
11812 .remove = advansys_pci_remove,
11813};
11814
11815static int __init advansys_init(void)
11816{
11817 int error;
11818
11819 error = isa_register_driver(&advansys_isa_driver,
11820 ASC_IOADR_TABLE_MAX_IX);
11821 if (error)
11822 goto fail;
11823
11824 error = isa_register_driver(&advansys_vlb_driver,
11825 ASC_IOADR_TABLE_MAX_IX);
11826 if (error)
11827 goto unregister_isa;
11828
11829 error = eisa_driver_register(&advansys_eisa_driver);
11830 if (error)
11831 goto unregister_vlb;
11832
11833 error = pci_register_driver(&advansys_pci_driver);
11834 if (error)
11835 goto unregister_eisa;
11836
11837 return 0;
11838
11839 unregister_eisa:
11840 eisa_driver_unregister(&advansys_eisa_driver);
11841 unregister_vlb:
11842 isa_unregister_driver(&advansys_vlb_driver);
11843 unregister_isa:
11844 isa_unregister_driver(&advansys_isa_driver);
11845 fail:
11846 return error;
11847}
11848
11849static void __exit advansys_exit(void)
11850{
11851 pci_unregister_driver(&advansys_pci_driver);
11852 eisa_driver_unregister(&advansys_eisa_driver);
11853 isa_unregister_driver(&advansys_vlb_driver);
11854 isa_unregister_driver(&advansys_isa_driver);
11855}
11856
11857module_init(advansys_init);
11858module_exit(advansys_exit);
11859
11860MODULE_LICENSE("GPL");
11861MODULE_FIRMWARE("advansys/mcode.bin");
11862MODULE_FIRMWARE("advansys/3550.bin");
11863MODULE_FIRMWARE("advansys/38C0800.bin");
11864MODULE_FIRMWARE("advansys/38C1600.bin");
11865