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