3 * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch.
5 * See file CREDITS for list of people who contributed to this
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
23 * linux/drivers/scsi/sym53c8xx.c
28 * SCSI support based on the chip sym53C810.
30 * 09-19-2001 Andreas Heppel, Sysgo RTS GmbH <aheppel@sysgo.de>
31 * The local version of this driver for the BAB750 board does not
32 * use interrupts but polls the chip instead (see the call of
33 * 'handle_scsi_int()' in 'scsi_issue()'.
38 #ifdef CONFIG_SCSI_SYM53C8XX
42 #include <asm/processor.h>
43 #include <sym53c8xx.h>
46 #undef SYM53C8XX_DEBUG
48 #ifdef SYM53C8XX_DEBUG
49 #define PRINTF(fmt,args...) printf (fmt ,##args)
51 #define PRINTF(fmt,args...)
54 #if defined(CONFIG_CMD_SCSI) && defined(CONFIG_SCSI_SYM53C8XX)
56 #undef SCSI_SINGLE_STEP
58 * Single Step is only used for debug purposes
60 #ifdef SCSI_SINGLE_STEP
61 static unsigned long start_script_select
;
62 static unsigned long start_script_msgout
;
63 static unsigned long start_script_msgin
;
64 static unsigned long start_script_msg_ext
;
65 static unsigned long start_script_cmd
;
66 static unsigned long start_script_data_in
;
67 static unsigned long start_script_data_out
;
68 static unsigned long start_script_status
;
69 static unsigned long start_script_complete
;
70 static unsigned long start_script_error
;
71 static unsigned long start_script_reselection
;
72 static unsigned int len_script_select
;
73 static unsigned int len_script_msgout
;
74 static unsigned int len_script_msgin
;
75 static unsigned int len_script_msg_ext
;
76 static unsigned int len_script_cmd
;
77 static unsigned int len_script_data_in
;
78 static unsigned int len_script_data_out
;
79 static unsigned int len_script_status
;
80 static unsigned int len_script_complete
;
81 static unsigned int len_script_error
;
82 static unsigned int len_script_reselection
;
86 static unsigned short scsi_int_mask
; /* shadow register for SCSI related interrupts */
87 static unsigned char script_int_mask
; /* shadow register for SCRIPT related interrupts */
88 static unsigned long script_select
[8]; /* script for selection */
89 static unsigned long script_msgout
[8]; /* script for message out phase (NOT USED) */
90 static unsigned long script_msgin
[14]; /* script for message in phase */
91 static unsigned long script_msg_ext
[32]; /* script for message in phase when more than 1 byte message */
92 static unsigned long script_cmd
[18]; /* script for command phase */
93 static unsigned long script_data_in
[8]; /* script for data in phase */
94 static unsigned long script_data_out
[8]; /* script for data out phase */
95 static unsigned long script_status
[6]; /* script for status phase */
96 static unsigned long script_complete
[10]; /* script for complete */
97 static unsigned long script_reselection
[4]; /* script for reselection (NOT USED) */
98 static unsigned long script_error
[2]; /* script for error handling */
100 static unsigned long int_stat
[3]; /* interrupt status */
101 static unsigned long scsi_mem_addr
; /* base memory address =SCSI_MEM_ADDRESS; */
103 #define bus_to_phys(a) pci_mem_to_phys(busdevfunc, (unsigned long) (a))
104 #define phys_to_bus(a) pci_phys_to_mem(busdevfunc, (unsigned long) (a))
106 #define SCSI_MAX_RETRY 3 /* number of retries in scsi_issue() */
108 #define SCSI_MAX_RETRY_NOT_READY 10 /* number of retries when device is not ready */
109 #define SCSI_NOT_READY_TIME_OUT 500 /* timeout per retry when not ready */
111 /*********************************************************************************
112 * forward declerations
115 void scsi_chip_init(void);
116 void handle_scsi_int(void);
119 /********************************************************************************
120 * reports SCSI errors to the user
122 void scsi_print_error(ccb
*pccb
)
125 printf("SCSI Error: Target %d LUN %d Command %02X\n",pccb
->target
, pccb
->lun
, pccb
->cmd
[0]);
127 for(i
=0;i
<pccb
->cmdlen
;i
++)
128 printf("%02X ",pccb
->cmd
[i
]);
129 printf("(len=%d)\n",pccb
->cmdlen
);
131 switch(pccb
->contr_stat
) {
132 case SIR_COMPLETE
: printf("Complete (no Error)\n"); break;
133 case SIR_SEL_ATN_NO_MSG_OUT
: printf("Selected with ATN no MSG out phase\n"); break;
134 case SIR_CMD_OUT_ILL_PH
: printf("Command out illegal phase\n"); break;
135 case SIR_MSG_RECEIVED
: printf("MSG received Error\n"); break;
136 case SIR_DATA_IN_ERR
: printf("Data in Error\n"); break;
137 case SIR_DATA_OUT_ERR
: printf("Data out Error\n"); break;
138 case SIR_SCRIPT_ERROR
: printf("Script Error\n"); break;
139 case SIR_MSG_OUT_NO_CMD
: printf("MSG out no Command phase\n"); break;
140 case SIR_MSG_OVER7
: printf("MSG in over 7 bytes\n"); break;
141 case INT_ON_FY
: printf("Interrupt on fly\n"); break;
142 case SCSI_SEL_TIME_OUT
: printf("SCSI Selection Timeout\n"); break;
143 case SCSI_HNS_TIME_OUT
: printf("SCSI Handshake Timeout\n"); break;
144 case SCSI_MA_TIME_OUT
: printf("SCSI Phase Error\n"); break;
145 case SCSI_UNEXP_DIS
: printf("SCSI unexpected disconnect\n"); break;
146 default: printf("unknown status %lx\n",pccb
->contr_stat
); break;
148 printf(" Sense: SK %x (",pccb
->sense_buf
[2]&0x0f);
149 switch(pccb
->sense_buf
[2]&0xf) {
150 case SENSE_NO_SENSE
: printf("No Sense)"); break;
151 case SENSE_RECOVERED_ERROR
: printf("Recovered Error)"); break;
152 case SENSE_NOT_READY
: printf("Not Ready)"); break;
153 case SENSE_MEDIUM_ERROR
: printf("Medium Error)"); break;
154 case SENSE_HARDWARE_ERROR
: printf("Hardware Error)"); break;
155 case SENSE_ILLEGAL_REQUEST
: printf("Illegal request)"); break;
156 case SENSE_UNIT_ATTENTION
: printf("Unit Attention)"); break;
157 case SENSE_DATA_PROTECT
: printf("Data Protect)"); break;
158 case SENSE_BLANK_CHECK
: printf("Blank check)"); break;
159 case SENSE_VENDOR_SPECIFIC
: printf("Vendor specific)"); break;
160 case SENSE_COPY_ABORTED
: printf("Copy aborted)"); break;
161 case SENSE_ABORTED_COMMAND
: printf("Aborted Command)"); break;
162 case SENSE_VOLUME_OVERFLOW
: printf("Volume overflow)"); break;
163 case SENSE_MISCOMPARE
: printf("Misscompare\n"); break;
164 default: printf("Illegal Sensecode\n"); break;
166 printf(" ASC %x ASCQ %x\n",pccb
->sense_buf
[12],pccb
->sense_buf
[13]);
168 switch(pccb
->status
) {
169 case S_GOOD
: printf("Good\n"); break;
170 case S_CHECK_COND
: printf("Check condition\n"); break;
171 case S_COND_MET
: printf("Condition Met\n"); break;
172 case S_BUSY
: printf("Busy\n"); break;
173 case S_INT
: printf("Intermediate\n"); break;
174 case S_INT_COND_MET
: printf("Intermediate condition met\n"); break;
175 case S_CONFLICT
: printf("Reservation conflict\n"); break;
176 case S_TERMINATED
: printf("Command terminated\n"); break;
177 case S_QUEUE_FULL
: printf("Task set full\n"); break;
178 default: printf("unknown: %02X\n",pccb
->status
); break;
184 /******************************************************************************
185 * sets-up the SCSI controller
186 * the base memory address is retrived via the pci_read_config_dword
188 void scsi_low_level_init(int busdevfunc
)
194 pci_read_config_byte(busdevfunc
, PCI_INTERRUPT_LINE
, &vec
);
195 pci_read_config_dword(busdevfunc
, PCI_BASE_ADDRESS_1
, &addr
);
197 addr
= bus_to_phys(addr
& ~0xf);
200 * Enable bus mastering in case this has not been done, yet.
202 pci_read_config_dword(busdevfunc
, PCI_COMMAND
, &cmd
);
203 cmd
|= PCI_COMMAND_MASTER
;
204 pci_write_config_dword(busdevfunc
, PCI_COMMAND
, cmd
);
206 scsi_mem_addr
= addr
;
213 /************************************************************************************
214 * Low level Part of SCSI Driver
218 * big-endian -> little endian conversion for the script
220 unsigned long swap_script(unsigned long val
)
223 tmp
= ((val
>>24)&0xff) | ((val
>>8)&0xff00) | ((val
<<8)&0xff0000) | ((val
<<24)&0xff000000);
228 void scsi_write_byte(ulong offset
,unsigned char val
)
230 out8(scsi_mem_addr
+offset
,val
);
234 unsigned char scsi_read_byte(ulong offset
)
236 return(in8(scsi_mem_addr
+offset
));
240 /********************************************************************************
243 void handle_scsi_int(void)
245 unsigned char stat
,stat1
,stat2
;
246 unsigned short sstat
;
248 #ifdef SCSI_SINGLE_STEP
251 stat
=scsi_read_byte(ISTAT
);
252 if((stat
& DIP
)==DIP
) { /* DMA Interrupt pending */
253 stat1
=scsi_read_byte(DSTAT
);
254 #ifdef SCSI_SINGLE_STEP
255 if((stat1
& SSI
)==SSI
)
257 tt
=in32r(scsi_mem_addr
+DSP
);
258 if(((tt
)>=start_script_select
) && ((tt
)<start_script_select
+len_script_select
)) {
259 printf("select %d\n",(tt
-start_script_select
)>>2);
262 if(((tt
)>=start_script_msgout
) && ((tt
)<start_script_msgout
+len_script_msgout
)) {
263 printf("msgout %d\n",(tt
-start_script_msgout
)>>2);
266 if(((tt
)>=start_script_msgin
) && ((tt
)<start_script_msgin
+len_script_msgin
)) {
267 printf("msgin %d\n",(tt
-start_script_msgin
)>>2);
270 if(((tt
)>=start_script_msg_ext
) && ((tt
)<start_script_msg_ext
+len_script_msg_ext
)) {
271 printf("msgin_ext %d\n",(tt
-start_script_msg_ext
)>>2);
274 if(((tt
)>=start_script_cmd
) && ((tt
)<start_script_cmd
+len_script_cmd
)) {
275 printf("cmd %d\n",(tt
-start_script_cmd
)>>2);
278 if(((tt
)>=start_script_data_in
) && ((tt
)<start_script_data_in
+len_script_data_in
)) {
279 printf("data_in %d\n",(tt
-start_script_data_in
)>>2);
282 if(((tt
)>=start_script_data_out
) && ((tt
)<start_script_data_out
+len_script_data_out
)) {
283 printf("data_out %d\n",(tt
-start_script_data_out
)>>2);
286 if(((tt
)>=start_script_status
) && ((tt
)<start_script_status
+len_script_status
)) {
287 printf("status %d\n",(tt
-start_script_status
)>>2);
290 if(((tt
)>=start_script_complete
) && ((tt
)<start_script_complete
+len_script_complete
)) {
291 printf("complete %d\n",(tt
-start_script_complete
)>>2);
294 if(((tt
)>=start_script_error
) && ((tt
)<start_script_error
+len_script_error
)) {
295 printf("error %d\n",(tt
-start_script_error
)>>2);
298 if(((tt
)>=start_script_reselection
) && ((tt
)<start_script_reselection
+len_script_reselection
)) {
299 printf("reselection %d\n",(tt
-start_script_reselection
)>>2);
302 printf("sc: %lx\n",tt
);
304 stat2
=scsi_read_byte(DCNTL
);
306 scsi_write_byte(DCNTL
,stat2
);
309 if((stat1
& SIR
)==SIR
) /* script interrupt */
311 int_stat
[0]=in32(scsi_mem_addr
+DSPS
);
313 if((stat1
& DFE
)==0) { /* fifo not epmty */
314 scsi_write_byte(CTEST3
,CLF
); /* Clear DMA FIFO */
315 stat2
=scsi_read_byte(STEST3
);
316 scsi_write_byte(STEST3
,(stat2
| CSF
)); /* Clear SCSI FIFO */
319 if((stat
& SIP
)==SIP
) { /* scsi interrupt */
320 sstat
= (unsigned short)scsi_read_byte(SIST
+1);
322 sstat
|= (unsigned short)scsi_read_byte(SIST
);
325 break; /* found an empty int status */
327 int_stat
[i
]=SCSI_INT_STATE
| sstat
;
328 stat1
=scsi_read_byte(DSTAT
);
329 if((stat1
& DFE
)==0) { /* fifo not epmty */
330 scsi_write_byte(CTEST3
,CLF
); /* Clear DMA FIFO */
331 stat2
=scsi_read_byte(STEST3
);
332 scsi_write_byte(STEST3
,(stat2
| CSF
)); /* Clear SCSI FIFO */
335 if((stat
& INTF
)==INTF
) { /* interrupt on Fly */
336 scsi_write_byte(ISTAT
,stat
); /* clear it */
339 break; /* found an empty int status */
341 int_stat
[i
]=INT_ON_FY
;
345 void scsi_bus_reset(void)
349 int end
= CFG_SCSI_SPIN_UP_TIME
*1000;
351 t
=scsi_read_byte(SCNTL1
);
352 scsi_write_byte(SCNTL1
,(t
| CRST
));
354 scsi_write_byte(SCNTL1
,t
);
356 puts("waiting for devices to spin up");
358 udelay(1000); /* give the devices time to spin up */
363 scsi_chip_init(); /* reinit the chip ...*/
367 void scsi_int_enable(void)
369 scsi_write_byte(SIEN
,(unsigned char)scsi_int_mask
);
370 scsi_write_byte(SIEN
+1,(unsigned char)(scsi_int_mask
>>8));
371 scsi_write_byte(DIEN
,script_int_mask
);
374 void scsi_write_dsp(unsigned long start
)
377 #ifdef SCSI_SINGLE_STEP
381 out32r(scsi_mem_addr
+ DSP
,start
);
382 #ifdef SCSI_SINGLE_STEP
383 t
=scsi_read_byte(DCNTL
);
385 scsi_write_byte(DCNTL
,t
);
389 /* only used for debug purposes */
390 void scsi_print_script(void)
392 printf("script_select @ 0x%08lX\n",(unsigned long)&script_select
[0]);
393 printf("script_msgout @ 0x%08lX\n",(unsigned long)&script_msgout
[0]);
394 printf("script_msgin @ 0x%08lX\n",(unsigned long)&script_msgin
[0]);
395 printf("script_msgext @ 0x%08lX\n",(unsigned long)&script_msg_ext
[0]);
396 printf("script_cmd @ 0x%08lX\n",(unsigned long)&script_cmd
[0]);
397 printf("script_data_in @ 0x%08lX\n",(unsigned long)&script_data_in
[0]);
398 printf("script_data_out @ 0x%08lX\n",(unsigned long)&script_data_out
[0]);
399 printf("script_status @ 0x%08lX\n",(unsigned long)&script_status
[0]);
400 printf("script_complete @ 0x%08lX\n",(unsigned long)&script_complete
[0]);
401 printf("script_error @ 0x%08lX\n",(unsigned long)&script_error
[0]);
405 void scsi_set_script(ccb
*pccb
)
407 int busdevfunc
= pccb
->priv
;
410 script_select
[i
++]=swap_script(SCR_REG_REG(GPREG
, SCR_AND
, 0xfe));
411 script_select
[i
++]=0; /* LED ON */
412 script_select
[i
++]=swap_script(SCR_CLR(SCR_TRG
)); /* select initiator mode */
413 script_select
[i
++]=0;
414 /* script_select[i++]=swap_script(SCR_SEL_ABS_ATN | pccb->target << 16); */
415 script_select
[i
++]=swap_script(SCR_SEL_ABS
| pccb
->target
<< 16);
416 script_select
[i
++]=swap_script(phys_to_bus(&script_cmd
[4])); /* error handling */
417 script_select
[i
++]=swap_script(SCR_JUMP
); /* next section */
418 /* script_select[i++]=swap_script((unsigned long)&script_msgout[0]); */ /* message out */
419 script_select
[i
++]=swap_script(phys_to_bus(&script_cmd
[0])); /* command out */
421 #ifdef SCSI_SINGLE_STEP
422 start_script_select
=(unsigned long)&script_select
[0];
423 len_script_select
=i
*4;
427 script_msgout
[i
++]=swap_script(SCR_INT
^ IFFALSE (WHEN (SCR_MSG_OUT
)));
428 script_msgout
[i
++]=SIR_SEL_ATN_NO_MSG_OUT
;
429 script_msgout
[i
++]=swap_script( SCR_MOVE_ABS(1) ^ SCR_MSG_OUT
);
430 script_msgout
[i
++]=swap_script(phys_to_bus(&pccb
->msgout
[0]));
431 script_msgout
[i
++]=swap_script(SCR_JUMP
^ IFTRUE (WHEN (SCR_COMMAND
))); /* if Command phase */
432 script_msgout
[i
++]=swap_script(phys_to_bus(&script_cmd
[0])); /* switch to command */
433 script_msgout
[i
++]=swap_script(SCR_INT
); /* interrupt if not */
434 script_msgout
[i
++]=SIR_MSG_OUT_NO_CMD
;
436 #ifdef SCSI_SINGLE_STEP
437 start_script_msgout
=(unsigned long)&script_msgout
[0];
438 len_script_msgout
=i
*4;
441 script_cmd
[i
++]=swap_script(SCR_MOVE_ABS(pccb
->cmdlen
) ^ SCR_COMMAND
);
442 script_cmd
[i
++]=swap_script(phys_to_bus(&pccb
->cmd
[0]));
443 script_cmd
[i
++]=swap_script(SCR_JUMP
^ IFTRUE (WHEN (SCR_MSG_IN
))); /* message in ? */
444 script_cmd
[i
++]=swap_script(phys_to_bus(&script_msgin
[0]));
445 script_cmd
[i
++]=swap_script(SCR_JUMP
^ IFTRUE (IF (SCR_DATA_OUT
))); /* data out ? */
446 script_cmd
[i
++]=swap_script(phys_to_bus(&script_data_out
[0]));
447 script_cmd
[i
++]=swap_script(SCR_JUMP
^ IFTRUE (IF (SCR_DATA_IN
))); /* data in ? */
448 script_cmd
[i
++]=swap_script(phys_to_bus(&script_data_in
[0]));
449 script_cmd
[i
++]=swap_script(SCR_JUMP
^ IFTRUE (IF (SCR_STATUS
))); /* status ? */
450 script_cmd
[i
++]=swap_script(phys_to_bus(&script_status
[0]));
451 script_cmd
[i
++]=swap_script(SCR_JUMP
^ IFTRUE (IF (SCR_COMMAND
))); /* command ? */
452 script_cmd
[i
++]=swap_script(phys_to_bus(&script_cmd
[0]));
453 script_cmd
[i
++]=swap_script(SCR_JUMP
^ IFTRUE (IF (SCR_MSG_OUT
))); /* message out ? */
454 script_cmd
[i
++]=swap_script(phys_to_bus(&script_msgout
[0]));
455 script_cmd
[i
++]=swap_script(SCR_JUMP
^ IFTRUE (IF (SCR_MSG_IN
))); /* just for error handling message in ? */
456 script_cmd
[i
++]=swap_script(phys_to_bus(&script_msgin
[0]));
457 script_cmd
[i
++]=swap_script(SCR_INT
); /* interrupt if not */
458 script_cmd
[i
++]=SIR_CMD_OUT_ILL_PH
;
459 #ifdef SCSI_SINGLE_STEP
460 start_script_cmd
=(unsigned long)&script_cmd
[0];
464 script_data_out
[i
++]=swap_script(SCR_MOVE_ABS(pccb
->datalen
)^ SCR_DATA_OUT
); /* move */
465 script_data_out
[i
++]=swap_script(phys_to_bus(pccb
->pdata
)); /* pointer to buffer */
466 script_data_out
[i
++]=swap_script(SCR_JUMP
^ IFTRUE (WHEN (SCR_STATUS
)));
467 script_data_out
[i
++]=swap_script(phys_to_bus(&script_status
[0]));
468 script_data_out
[i
++]=swap_script(SCR_INT
);
469 script_data_out
[i
++]=SIR_DATA_OUT_ERR
;
471 #ifdef SCSI_SINGLE_STEP
472 start_script_data_out
=(unsigned long)&script_data_out
[0];
473 len_script_data_out
=i
*4;
476 script_data_in
[i
++]=swap_script(SCR_MOVE_ABS(pccb
->datalen
)^ SCR_DATA_IN
); /* move */
477 script_data_in
[i
++]=swap_script(phys_to_bus(pccb
->pdata
)); /* pointer to buffer */
478 script_data_in
[i
++]=swap_script(SCR_JUMP
^ IFTRUE (WHEN (SCR_STATUS
)));
479 script_data_in
[i
++]=swap_script(phys_to_bus(&script_status
[0]));
480 script_data_in
[i
++]=swap_script(SCR_INT
);
481 script_data_in
[i
++]=SIR_DATA_IN_ERR
;
482 #ifdef SCSI_SINGLE_STEP
483 start_script_data_in
=(unsigned long)&script_data_in
[0];
484 len_script_data_in
=i
*4;
487 script_msgin
[i
++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN
);
488 script_msgin
[i
++]=swap_script(phys_to_bus(&pccb
->msgin
[0]));
489 script_msgin
[i
++]=swap_script(SCR_JUMP
^ IFTRUE (DATA (M_COMPLETE
)));
490 script_msgin
[i
++]=swap_script(phys_to_bus(&script_complete
[0]));
491 script_msgin
[i
++]=swap_script(SCR_JUMP
^ IFTRUE (DATA (M_DISCONNECT
)));
492 script_msgin
[i
++]=swap_script(phys_to_bus(&script_complete
[0]));
493 script_msgin
[i
++]=swap_script(SCR_JUMP
^ IFTRUE (DATA (M_SAVE_DP
)));
494 script_msgin
[i
++]=swap_script(phys_to_bus(&script_complete
[0]));
495 script_msgin
[i
++]=swap_script(SCR_JUMP
^ IFTRUE (DATA (M_RESTORE_DP
)));
496 script_msgin
[i
++]=swap_script(phys_to_bus(&script_complete
[0]));
497 script_msgin
[i
++]=swap_script(SCR_JUMP
^ IFTRUE (DATA (M_EXTENDED
)));
498 script_msgin
[i
++]=swap_script(phys_to_bus(&script_msg_ext
[0]));
499 script_msgin
[i
++]=swap_script(SCR_INT
);
500 script_msgin
[i
++]=SIR_MSG_RECEIVED
;
501 #ifdef SCSI_SINGLE_STEP
502 start_script_msgin
=(unsigned long)&script_msgin
[0];
503 len_script_msgin
=i
*4;
506 script_msg_ext
[i
++]=swap_script(SCR_CLR (SCR_ACK
)); /* clear ACK */
507 script_msg_ext
[i
++]=0;
508 script_msg_ext
[i
++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN
); /* assuming this is the msg length */
509 script_msg_ext
[i
++]=swap_script(phys_to_bus(&pccb
->msgin
[1]));
510 script_msg_ext
[i
++]=swap_script(SCR_JUMP
^ IFFALSE (IF (SCR_MSG_IN
)));
511 script_msg_ext
[i
++]=swap_script(phys_to_bus(&script_complete
[0])); /* no more bytes */
512 script_msg_ext
[i
++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN
); /* next */
513 script_msg_ext
[i
++]=swap_script(phys_to_bus(&pccb
->msgin
[2]));
514 script_msg_ext
[i
++]=swap_script(SCR_JUMP
^ IFFALSE (IF (SCR_MSG_IN
)));
515 script_msg_ext
[i
++]=swap_script(phys_to_bus(&script_complete
[0])); /* no more bytes */
516 script_msg_ext
[i
++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN
); /* next */
517 script_msg_ext
[i
++]=swap_script(phys_to_bus(&pccb
->msgin
[3]));
518 script_msg_ext
[i
++]=swap_script(SCR_JUMP
^ IFFALSE (IF (SCR_MSG_IN
)));
519 script_msg_ext
[i
++]=swap_script(phys_to_bus(&script_complete
[0])); /* no more bytes */
520 script_msg_ext
[i
++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN
); /* next */
521 script_msg_ext
[i
++]=swap_script(phys_to_bus(&pccb
->msgin
[4]));
522 script_msg_ext
[i
++]=swap_script(SCR_JUMP
^ IFFALSE (IF (SCR_MSG_IN
)));
523 script_msg_ext
[i
++]=swap_script(phys_to_bus(&script_complete
[0])); /* no more bytes */
524 script_msg_ext
[i
++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN
); /* next */
525 script_msg_ext
[i
++]=swap_script(phys_to_bus(&pccb
->msgin
[5]));
526 script_msg_ext
[i
++]=swap_script(SCR_JUMP
^ IFFALSE (IF (SCR_MSG_IN
)));
527 script_msg_ext
[i
++]=swap_script(phys_to_bus(&script_complete
[0])); /* no more bytes */
528 script_msg_ext
[i
++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN
); /* next */
529 script_msg_ext
[i
++]=swap_script(phys_to_bus(&pccb
->msgin
[6]));
530 script_msg_ext
[i
++]=swap_script(SCR_JUMP
^ IFFALSE (IF (SCR_MSG_IN
)));
531 script_msg_ext
[i
++]=swap_script(phys_to_bus(&script_complete
[0])); /* no more bytes */
532 script_msg_ext
[i
++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN
); /* next */
533 script_msg_ext
[i
++]=swap_script(phys_to_bus(&pccb
->msgin
[7]));
534 script_msg_ext
[i
++]=swap_script(SCR_JUMP
^ IFFALSE (IF (SCR_MSG_IN
)));
535 script_msg_ext
[i
++]=swap_script(phys_to_bus(&script_complete
[0])); /* no more bytes */
536 script_msg_ext
[i
++]=swap_script(SCR_INT
);
537 script_msg_ext
[i
++]=SIR_MSG_OVER7
;
538 #ifdef SCSI_SINGLE_STEP
539 start_script_msg_ext
=(unsigned long)&script_msg_ext
[0];
540 len_script_msg_ext
=i
*4;
543 script_status
[i
++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_STATUS
);
544 script_status
[i
++]=swap_script(phys_to_bus(&pccb
->status
));
545 script_status
[i
++]=swap_script(SCR_JUMP
^ IFTRUE (WHEN (SCR_MSG_IN
)));
546 script_status
[i
++]=swap_script(phys_to_bus(&script_msgin
[0]));
547 script_status
[i
++]=swap_script(SCR_INT
);
548 script_status
[i
++]=SIR_STATUS_ILL_PH
;
549 #ifdef SCSI_SINGLE_STEP
550 start_script_status
=(unsigned long)&script_status
[0];
551 len_script_status
=i
*4;
554 script_complete
[i
++]=swap_script(SCR_REG_REG (SCNTL2
, SCR_AND
, 0x7f));
555 script_complete
[i
++]=0;
556 script_complete
[i
++]=swap_script(SCR_CLR (SCR_ACK
|SCR_ATN
));
557 script_complete
[i
++]=0;
558 script_complete
[i
++]=swap_script(SCR_WAIT_DISC
);
559 script_complete
[i
++]=0;
560 script_complete
[i
++]=swap_script(SCR_REG_REG(GPREG
, SCR_OR
, 0x01));
561 script_complete
[i
++]=0; /* LED OFF */
562 script_complete
[i
++]=swap_script(SCR_INT
);
563 script_complete
[i
++]=SIR_COMPLETE
;
564 #ifdef SCSI_SINGLE_STEP
565 start_script_complete
=(unsigned long)&script_complete
[0];
566 len_script_complete
=i
*4;
569 script_error
[i
++]=swap_script(SCR_INT
); /* interrupt if error */
570 script_error
[i
++]=SIR_SCRIPT_ERROR
;
571 #ifdef SCSI_SINGLE_STEP
572 start_script_error
=(unsigned long)&script_error
[0];
573 len_script_error
=i
*4;
576 script_reselection
[i
++]=swap_script(SCR_CLR (SCR_TRG
)); /* target status */
577 script_reselection
[i
++]=0;
578 script_reselection
[i
++]=swap_script(SCR_WAIT_RESEL
);
579 script_reselection
[i
++]=swap_script(phys_to_bus(&script_select
[0])); /* len = 4 */
580 #ifdef SCSI_SINGLE_STEP
581 start_script_reselection
=(unsigned long)&script_reselection
[0];
582 len_script_reselection
=i
*4;
587 void scsi_issue(ccb
*pccb
)
589 int busdevfunc
= pccb
->priv
;
591 unsigned short sstat
;
592 int retrycnt
; /* retry counter */
594 int_stat
[i
]=0; /* delete all int status */
595 /* struct pccb must be set-up correctly */
597 PRINTF("ID %d issue cmd %02X\n",pccb
->target
,pccb
->cmd
[0]);
598 pccb
->trans_bytes
=0; /* no bytes transfered yet */
599 scsi_set_script(pccb
); /* fill in SCRIPT */
600 scsi_int_mask
=STO
| UDC
| MA
; /* | CMP; / * Interrupts which are enabled */
601 script_int_mask
=0xff; /* enable all Ints */
603 scsi_write_dsp(phys_to_bus(&script_select
[0])); /* start script */
604 /* now we have to wait for IRQs */
607 * This version of the driver is _not_ interrupt driven,
608 * but polls the chip's interrupt registers (ISTAT, DSTAT).
610 while(int_stat
[0]==0)
613 if(int_stat
[0]==SIR_COMPLETE
) {
614 if(pccb
->msgin
[0]==M_DISCONNECT
) {
615 PRINTF("Wait for reselection\n");
617 int_stat
[i
]=0; /* delete all int status */
618 scsi_write_dsp(phys_to_bus(&script_reselection
[0])); /* start reselection script */
621 pccb
->contr_stat
=SIR_COMPLETE
;
624 if((int_stat
[0] & SCSI_INT_STATE
)==SCSI_INT_STATE
) { /* scsi interrupt */
625 sstat
=(unsigned short)int_stat
[0];
626 if((sstat
& STO
)==STO
) { /* selection timeout */
627 pccb
->contr_stat
=SCSI_SEL_TIME_OUT
;
628 scsi_write_byte(GPREG
,0x01);
629 PRINTF("ID: %X Selection Timeout\n",pccb
->target
);
632 if((sstat
& UDC
)==UDC
) { /* unexpected disconnect */
633 pccb
->contr_stat
=SCSI_UNEXP_DIS
;
634 scsi_write_byte(GPREG
,0x01);
635 PRINTF("ID: %X Unexpected Disconnect\n",pccb
->target
);
638 if((sstat
& RSL
)==RSL
) { /* reselection */
639 pccb
->contr_stat
=SCSI_UNEXP_DIS
;
640 scsi_write_byte(GPREG
,0x01);
641 PRINTF("ID: %X Unexpected Disconnect\n",pccb
->target
);
644 if(((sstat
& MA
)==MA
)||((sstat
& HTH
)==HTH
)) { /* phase missmatch */
645 if(retrycnt
<SCSI_MAX_RETRY
) {
646 pccb
->trans_bytes
=pccb
->datalen
-
647 ((unsigned long)scsi_read_byte(DBC
) |
648 ((unsigned long)scsi_read_byte(DBC
+1)<<8) |
649 ((unsigned long)scsi_read_byte(DBC
+2)<<16));
651 int_stat
[i
]=0; /* delete all int status */
653 PRINTF("ID: %X Phase Missmatch Retry %d Phase %02X transfered %lx\n",
654 pccb
->target
,retrycnt
,scsi_read_byte(SBCL
),pccb
->trans_bytes
);
655 scsi_write_dsp(phys_to_bus(&script_cmd
[4])); /* start retry script */
659 pccb
->contr_stat
=SCSI_MA_TIME_OUT
;
661 pccb
->contr_stat
=SCSI_HNS_TIME_OUT
;
662 PRINTF("Phase Missmatch stat %lx\n",pccb
->contr_stat
);
665 /* if((sstat & CMP)==CMP) {
666 pccb->contr_stat=SIR_COMPLETE;
670 PRINTF("SCSI INT %lX\n",int_stat
[0]);
671 pccb
->contr_stat
=int_stat
[0];
674 PRINTF("SCRIPT INT %lX phase %02X\n",int_stat
[0],scsi_read_byte(SBCL
));
675 pccb
->contr_stat
=int_stat
[0];
679 int scsi_exec(ccb
*pccb
)
681 unsigned char tmpcmd
[16],tmpstat
;
683 unsigned long transbytes
,datalen
;
684 unsigned char *tmpptr
;
688 if(pccb
->contr_stat
!=SIR_COMPLETE
)
690 if(pccb
->status
==S_GOOD
)
692 if(pccb
->status
==S_CHECK_COND
) { /* check condition */
694 tmpcmd
[i
]=pccb
->cmd
[i
];
695 pccb
->cmd
[0]=SCSI_REQ_SENSE
;
696 pccb
->cmd
[1]=pccb
->lun
<<5;
702 pccb
->msgout
[0]=SCSI_IDENTIFY
;
703 transbytes
=pccb
->trans_bytes
;
705 pccb
->pdata
=&pccb
->sense_buf
[0];
706 datalen
=pccb
->datalen
;
708 tmpstat
=pccb
->status
;
711 pccb
->cmd
[i
]=tmpcmd
[i
];
712 pccb
->trans_bytes
=transbytes
;
714 pccb
->datalen
=datalen
;
715 pccb
->status
=tmpstat
;
716 PRINTF("Request_sense sense key %x ASC %x ASCQ %x\n",pccb
->sense_buf
[2]&0x0f,
717 pccb
->sense_buf
[12],pccb
->sense_buf
[13]);
718 switch(pccb
->sense_buf
[2]&0xf) {
720 case SENSE_RECOVERED_ERROR
:
724 case SENSE_NOT_READY
:
725 if((pccb
->sense_buf
[12]!=0x04)||(pccb
->sense_buf
[13]!=0x01)) {
726 /* if device is not in process of becoming ready */
729 } /* else fall through */
730 case SENSE_UNIT_ATTENTION
:
731 if(retrycnt
<SCSI_MAX_RETRY_NOT_READY
) {
732 PRINTF("Target %d not ready, retry %d\n",pccb
->target
,retrycnt
);
733 for(t
=0;t
<SCSI_NOT_READY_TIME_OUT
;t
++)
734 udelay(1000); /* 1sec wait */
738 PRINTF("Target %d not ready, %d retried\n",pccb
->target
,retrycnt
);
744 PRINTF("Status = %X\n",pccb
->status
);
749 void scsi_chip_init(void)
751 /* first we issue a soft reset */
752 scsi_write_byte(ISTAT
,SRST
);
754 scsi_write_byte(ISTAT
,0);
756 scsi_write_byte(SCNTL0
,0xC0); /* full arbitration no start, no message, parity disabled, master */
757 scsi_write_byte(SCNTL1
,0x00);
758 scsi_write_byte(SCNTL2
,0x00);
759 #ifndef CFG_SCSI_SYM53C8XX_CCF /* config value for none 40 mhz clocks */
760 scsi_write_byte(SCNTL3
,0x13); /* synchronous clock 40/4=10MHz, asynchronous 40MHz */
762 scsi_write_byte(SCNTL3
,CFG_SCSI_SYM53C8XX_CCF
); /* config value for none 40 mhz clocks */
764 scsi_write_byte(SCID
,0x47); /* ID=7, enable reselection */
765 scsi_write_byte(SXFER
,0x00); /* synchronous transfer period 10MHz, asynchronous */
766 scsi_write_byte(SDID
,0x00); /* targed SCSI ID = 0 */
767 scsi_int_mask
=0x0000; /* no Interrupt is enabled */
768 script_int_mask
=0x00;
770 scsi_write_byte(GPREG
,0x01); /* GPIO0 is LED (off) */
771 scsi_write_byte(GPCNTL
,0x0E); /* GPIO0 is Output */
772 scsi_write_byte(STIME0
,0x08); /* handshake timer disabled, selection timeout 512msec */
773 scsi_write_byte(RESPID
,0x80); /* repond only to the own ID (reselection) */
774 scsi_write_byte(STEST1
,0x00); /* not isolated, SCLK is used */
775 scsi_write_byte(STEST2
,0x00); /* no Lowlevel Mode? */
776 scsi_write_byte(STEST3
,0x80); /* enable tolerANT */
777 scsi_write_byte(CTEST3
,0x04); /* clear FIFO */
778 scsi_write_byte(CTEST4
,0x00);
779 scsi_write_byte(CTEST5
,0x00);
780 #ifdef SCSI_SINGLE_STEP
781 /* scsi_write_byte(DCNTL,IRQM | SSM); */
782 scsi_write_byte(DCNTL
,IRQD
| SSM
);
783 scsi_write_byte(DMODE
,MAN
);
785 /* scsi_write_byte(DCNTL,IRQM); */
786 scsi_write_byte(DCNTL
,IRQD
);
787 scsi_write_byte(DMODE
,0x00);
793 #endif /* CONFIG_SCSI_SYM53C8XX */