]>
git.ipfire.org Git - people/ms/u-boot.git/blob - drivers/block/sym53c8xx.c
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()'.
40 #include <asm/processor.h>
41 #include <sym53c8xx.h>
44 #undef SYM53C8XX_DEBUG
46 #ifdef SYM53C8XX_DEBUG
47 #define PRINTF(fmt,args...) printf (fmt ,##args)
49 #define PRINTF(fmt,args...)
52 #if defined(CONFIG_CMD_SCSI) && defined(CONFIG_SCSI_SYM53C8XX)
54 #undef SCSI_SINGLE_STEP
56 * Single Step is only used for debug purposes
58 #ifdef SCSI_SINGLE_STEP
59 static unsigned long start_script_select
;
60 static unsigned long start_script_msgout
;
61 static unsigned long start_script_msgin
;
62 static unsigned long start_script_msg_ext
;
63 static unsigned long start_script_cmd
;
64 static unsigned long start_script_data_in
;
65 static unsigned long start_script_data_out
;
66 static unsigned long start_script_status
;
67 static unsigned long start_script_complete
;
68 static unsigned long start_script_error
;
69 static unsigned long start_script_reselection
;
70 static unsigned int len_script_select
;
71 static unsigned int len_script_msgout
;
72 static unsigned int len_script_msgin
;
73 static unsigned int len_script_msg_ext
;
74 static unsigned int len_script_cmd
;
75 static unsigned int len_script_data_in
;
76 static unsigned int len_script_data_out
;
77 static unsigned int len_script_status
;
78 static unsigned int len_script_complete
;
79 static unsigned int len_script_error
;
80 static unsigned int len_script_reselection
;
84 static unsigned short scsi_int_mask
; /* shadow register for SCSI related interrupts */
85 static unsigned char script_int_mask
; /* shadow register for SCRIPT related interrupts */
86 static unsigned long script_select
[8]; /* script for selection */
87 static unsigned long script_msgout
[8]; /* script for message out phase (NOT USED) */
88 static unsigned long script_msgin
[14]; /* script for message in phase */
89 static unsigned long script_msg_ext
[32]; /* script for message in phase when more than 1 byte message */
90 static unsigned long script_cmd
[18]; /* script for command phase */
91 static unsigned long script_data_in
[8]; /* script for data in phase */
92 static unsigned long script_data_out
[8]; /* script for data out phase */
93 static unsigned long script_status
[6]; /* script for status phase */
94 static unsigned long script_complete
[10]; /* script for complete */
95 static unsigned long script_reselection
[4]; /* script for reselection (NOT USED) */
96 static unsigned long script_error
[2]; /* script for error handling */
98 static unsigned long int_stat
[3]; /* interrupt status */
99 static unsigned long scsi_mem_addr
; /* base memory address =SCSI_MEM_ADDRESS; */
101 #define bus_to_phys(a) pci_mem_to_phys(busdevfunc, (unsigned long) (a))
102 #define phys_to_bus(a) pci_phys_to_mem(busdevfunc, (unsigned long) (a))
104 #define SCSI_MAX_RETRY 3 /* number of retries in scsi_issue() */
106 #define SCSI_MAX_RETRY_NOT_READY 10 /* number of retries when device is not ready */
107 #define SCSI_NOT_READY_TIME_OUT 500 /* timeout per retry when not ready */
109 /*********************************************************************************
110 * forward declerations
113 void scsi_chip_init(void);
114 void handle_scsi_int(void);
117 /********************************************************************************
118 * reports SCSI errors to the user
120 void scsi_print_error (ccb
* pccb
)
124 printf ("SCSI Error: Target %d LUN %d Command %02X\n", pccb
->target
,
125 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
) {
133 printf ("Complete (no Error)\n");
135 case SIR_SEL_ATN_NO_MSG_OUT
:
136 printf ("Selected with ATN no MSG out phase\n");
138 case SIR_CMD_OUT_ILL_PH
:
139 printf ("Command out illegal phase\n");
141 case SIR_MSG_RECEIVED
:
142 printf ("MSG received Error\n");
144 case SIR_DATA_IN_ERR
:
145 printf ("Data in Error\n");
147 case SIR_DATA_OUT_ERR
:
148 printf ("Data out Error\n");
150 case SIR_SCRIPT_ERROR
:
151 printf ("Script Error\n");
153 case SIR_MSG_OUT_NO_CMD
:
154 printf ("MSG out no Command phase\n");
157 printf ("MSG in over 7 bytes\n");
160 printf ("Interrupt on fly\n");
162 case SCSI_SEL_TIME_OUT
:
163 printf ("SCSI Selection Timeout\n");
165 case SCSI_HNS_TIME_OUT
:
166 printf ("SCSI Handshake Timeout\n");
168 case SCSI_MA_TIME_OUT
:
169 printf ("SCSI Phase Error\n");
172 printf ("SCSI unexpected disconnect\n");
175 printf ("unknown status %lx\n", pccb
->contr_stat
);
178 printf (" Sense: SK %x (", pccb
->sense_buf
[2] & 0x0f);
179 switch (pccb
->sense_buf
[2] & 0xf) {
181 printf ("No Sense)");
183 case SENSE_RECOVERED_ERROR
:
184 printf ("Recovered Error)");
186 case SENSE_NOT_READY
:
187 printf ("Not Ready)");
189 case SENSE_MEDIUM_ERROR
:
190 printf ("Medium Error)");
192 case SENSE_HARDWARE_ERROR
:
193 printf ("Hardware Error)");
195 case SENSE_ILLEGAL_REQUEST
:
196 printf ("Illegal request)");
198 case SENSE_UNIT_ATTENTION
:
199 printf ("Unit Attention)");
201 case SENSE_DATA_PROTECT
:
202 printf ("Data Protect)");
204 case SENSE_BLANK_CHECK
:
205 printf ("Blank check)");
207 case SENSE_VENDOR_SPECIFIC
:
208 printf ("Vendor specific)");
210 case SENSE_COPY_ABORTED
:
211 printf ("Copy aborted)");
213 case SENSE_ABORTED_COMMAND
:
214 printf ("Aborted Command)");
216 case SENSE_VOLUME_OVERFLOW
:
217 printf ("Volume overflow)");
219 case SENSE_MISCOMPARE
:
220 printf ("Misscompare\n");
223 printf ("Illegal Sensecode\n");
226 printf (" ASC %x ASCQ %x\n", pccb
->sense_buf
[12],
227 pccb
->sense_buf
[13]);
228 printf (" Status: ");
229 switch (pccb
->status
) {
234 printf ("Check condition\n");
237 printf ("Condition Met\n");
243 printf ("Intermediate\n");
246 printf ("Intermediate condition met\n");
249 printf ("Reservation conflict\n");
252 printf ("Command terminated\n");
255 printf ("Task set full\n");
258 printf ("unknown: %02X\n", pccb
->status
);
265 /******************************************************************************
266 * sets-up the SCSI controller
267 * the base memory address is retrived via the pci_read_config_dword
269 void scsi_low_level_init(int busdevfunc
)
275 pci_read_config_byte(busdevfunc
, PCI_INTERRUPT_LINE
, &vec
);
276 pci_read_config_dword(busdevfunc
, PCI_BASE_ADDRESS_1
, &addr
);
278 addr
= bus_to_phys(addr
& ~0xf);
281 * Enable bus mastering in case this has not been done, yet.
283 pci_read_config_dword(busdevfunc
, PCI_COMMAND
, &cmd
);
284 cmd
|= PCI_COMMAND_MASTER
;
285 pci_write_config_dword(busdevfunc
, PCI_COMMAND
, cmd
);
287 scsi_mem_addr
= addr
;
294 /************************************************************************************
295 * Low level Part of SCSI Driver
299 * big-endian -> little endian conversion for the script
301 unsigned long swap_script(unsigned long val
)
304 tmp
= ((val
>>24)&0xff) | ((val
>>8)&0xff00) | ((val
<<8)&0xff0000) | ((val
<<24)&0xff000000);
309 void scsi_write_byte(ulong offset
,unsigned char val
)
311 out8(scsi_mem_addr
+offset
,val
);
315 unsigned char scsi_read_byte(ulong offset
)
317 return(in8(scsi_mem_addr
+offset
));
321 /********************************************************************************
324 void handle_scsi_int(void)
326 unsigned char stat
,stat1
,stat2
;
327 unsigned short sstat
;
329 #ifdef SCSI_SINGLE_STEP
332 stat
=scsi_read_byte(ISTAT
);
333 if((stat
& DIP
)==DIP
) { /* DMA Interrupt pending */
334 stat1
=scsi_read_byte(DSTAT
);
335 #ifdef SCSI_SINGLE_STEP
336 if((stat1
& SSI
)==SSI
) {
337 tt
=in32r(scsi_mem_addr
+DSP
);
338 if(((tt
)>=start_script_select
) && ((tt
)<start_script_select
+len_script_select
)) {
339 printf("select %d\n",(tt
-start_script_select
)>>2);
342 if(((tt
)>=start_script_msgout
) && ((tt
)<start_script_msgout
+len_script_msgout
)) {
343 printf("msgout %d\n",(tt
-start_script_msgout
)>>2);
346 if(((tt
)>=start_script_msgin
) && ((tt
)<start_script_msgin
+len_script_msgin
)) {
347 printf("msgin %d\n",(tt
-start_script_msgin
)>>2);
350 if(((tt
)>=start_script_msg_ext
) && ((tt
)<start_script_msg_ext
+len_script_msg_ext
)) {
351 printf("msgin_ext %d\n",(tt
-start_script_msg_ext
)>>2);
354 if(((tt
)>=start_script_cmd
) && ((tt
)<start_script_cmd
+len_script_cmd
)) {
355 printf("cmd %d\n",(tt
-start_script_cmd
)>>2);
358 if(((tt
)>=start_script_data_in
) && ((tt
)<start_script_data_in
+len_script_data_in
)) {
359 printf("data_in %d\n",(tt
-start_script_data_in
)>>2);
362 if(((tt
)>=start_script_data_out
) && ((tt
)<start_script_data_out
+len_script_data_out
)) {
363 printf("data_out %d\n",(tt
-start_script_data_out
)>>2);
366 if(((tt
)>=start_script_status
) && ((tt
)<start_script_status
+len_script_status
)) {
367 printf("status %d\n",(tt
-start_script_status
)>>2);
370 if(((tt
)>=start_script_complete
) && ((tt
)<start_script_complete
+len_script_complete
)) {
371 printf("complete %d\n",(tt
-start_script_complete
)>>2);
374 if(((tt
)>=start_script_error
) && ((tt
)<start_script_error
+len_script_error
)) {
375 printf("error %d\n",(tt
-start_script_error
)>>2);
378 if(((tt
)>=start_script_reselection
) && ((tt
)<start_script_reselection
+len_script_reselection
)) {
379 printf("reselection %d\n",(tt
-start_script_reselection
)>>2);
382 printf("sc: %lx\n",tt
);
384 stat2
=scsi_read_byte(DCNTL
);
386 scsi_write_byte(DCNTL
,stat2
);
389 if((stat1
& SIR
)==SIR
) /* script interrupt */
391 int_stat
[0]=in32(scsi_mem_addr
+DSPS
);
393 if((stat1
& DFE
)==0) { /* fifo not epmty */
394 scsi_write_byte(CTEST3
,CLF
); /* Clear DMA FIFO */
395 stat2
=scsi_read_byte(STEST3
);
396 scsi_write_byte(STEST3
,(stat2
| CSF
)); /* Clear SCSI FIFO */
399 if((stat
& SIP
)==SIP
) { /* scsi interrupt */
400 sstat
= (unsigned short)scsi_read_byte(SIST
+1);
402 sstat
|= (unsigned short)scsi_read_byte(SIST
);
405 break; /* found an empty int status */
407 int_stat
[i
]=SCSI_INT_STATE
| sstat
;
408 stat1
=scsi_read_byte(DSTAT
);
409 if((stat1
& DFE
)==0) { /* fifo not epmty */
410 scsi_write_byte(CTEST3
,CLF
); /* Clear DMA FIFO */
411 stat2
=scsi_read_byte(STEST3
);
412 scsi_write_byte(STEST3
,(stat2
| CSF
)); /* Clear SCSI FIFO */
415 if((stat
& INTF
)==INTF
) { /* interrupt on Fly */
416 scsi_write_byte(ISTAT
,stat
); /* clear it */
419 break; /* found an empty int status */
421 int_stat
[i
]=INT_ON_FY
;
425 void scsi_bus_reset(void)
429 int end
= CFG_SCSI_SPIN_UP_TIME
*1000;
431 t
=scsi_read_byte(SCNTL1
);
432 scsi_write_byte(SCNTL1
,(t
| CRST
));
434 scsi_write_byte(SCNTL1
,t
);
436 puts("waiting for devices to spin up");
438 udelay(1000); /* give the devices time to spin up */
443 scsi_chip_init(); /* reinit the chip ...*/
447 void scsi_int_enable(void)
449 scsi_write_byte(SIEN
,(unsigned char)scsi_int_mask
);
450 scsi_write_byte(SIEN
+1,(unsigned char)(scsi_int_mask
>>8));
451 scsi_write_byte(DIEN
,script_int_mask
);
454 void scsi_write_dsp(unsigned long start
)
457 #ifdef SCSI_SINGLE_STEP
461 out32r(scsi_mem_addr
+ DSP
,start
);
462 #ifdef SCSI_SINGLE_STEP
463 t
=scsi_read_byte(DCNTL
);
465 scsi_write_byte(DCNTL
,t
);
469 /* only used for debug purposes */
470 void scsi_print_script(void)
472 printf("script_select @ 0x%08lX\n",(unsigned long)&script_select
[0]);
473 printf("script_msgout @ 0x%08lX\n",(unsigned long)&script_msgout
[0]);
474 printf("script_msgin @ 0x%08lX\n",(unsigned long)&script_msgin
[0]);
475 printf("script_msgext @ 0x%08lX\n",(unsigned long)&script_msg_ext
[0]);
476 printf("script_cmd @ 0x%08lX\n",(unsigned long)&script_cmd
[0]);
477 printf("script_data_in @ 0x%08lX\n",(unsigned long)&script_data_in
[0]);
478 printf("script_data_out @ 0x%08lX\n",(unsigned long)&script_data_out
[0]);
479 printf("script_status @ 0x%08lX\n",(unsigned long)&script_status
[0]);
480 printf("script_complete @ 0x%08lX\n",(unsigned long)&script_complete
[0]);
481 printf("script_error @ 0x%08lX\n",(unsigned long)&script_error
[0]);
485 void scsi_set_script(ccb
*pccb
)
487 int busdevfunc
= pccb
->priv
;
490 script_select
[i
++]=swap_script(SCR_REG_REG(GPREG
, SCR_AND
, 0xfe));
491 script_select
[i
++]=0; /* LED ON */
492 script_select
[i
++]=swap_script(SCR_CLR(SCR_TRG
)); /* select initiator mode */
493 script_select
[i
++]=0;
494 /* script_select[i++]=swap_script(SCR_SEL_ABS_ATN | pccb->target << 16); */
495 script_select
[i
++]=swap_script(SCR_SEL_ABS
| pccb
->target
<< 16);
496 script_select
[i
++]=swap_script(phys_to_bus(&script_cmd
[4])); /* error handling */
497 script_select
[i
++]=swap_script(SCR_JUMP
); /* next section */
498 /* script_select[i++]=swap_script((unsigned long)&script_msgout[0]); */ /* message out */
499 script_select
[i
++]=swap_script(phys_to_bus(&script_cmd
[0])); /* command out */
501 #ifdef SCSI_SINGLE_STEP
502 start_script_select
=(unsigned long)&script_select
[0];
503 len_script_select
=i
*4;
507 script_msgout
[i
++]=swap_script(SCR_INT
^ IFFALSE (WHEN (SCR_MSG_OUT
)));
508 script_msgout
[i
++]=SIR_SEL_ATN_NO_MSG_OUT
;
509 script_msgout
[i
++]=swap_script( SCR_MOVE_ABS(1) ^ SCR_MSG_OUT
);
510 script_msgout
[i
++]=swap_script(phys_to_bus(&pccb
->msgout
[0]));
511 script_msgout
[i
++]=swap_script(SCR_JUMP
^ IFTRUE (WHEN (SCR_COMMAND
))); /* if Command phase */
512 script_msgout
[i
++]=swap_script(phys_to_bus(&script_cmd
[0])); /* switch to command */
513 script_msgout
[i
++]=swap_script(SCR_INT
); /* interrupt if not */
514 script_msgout
[i
++]=SIR_MSG_OUT_NO_CMD
;
516 #ifdef SCSI_SINGLE_STEP
517 start_script_msgout
=(unsigned long)&script_msgout
[0];
518 len_script_msgout
=i
*4;
521 script_cmd
[i
++]=swap_script(SCR_MOVE_ABS(pccb
->cmdlen
) ^ SCR_COMMAND
);
522 script_cmd
[i
++]=swap_script(phys_to_bus(&pccb
->cmd
[0]));
523 script_cmd
[i
++]=swap_script(SCR_JUMP
^ IFTRUE (WHEN (SCR_MSG_IN
))); /* message in ? */
524 script_cmd
[i
++]=swap_script(phys_to_bus(&script_msgin
[0]));
525 script_cmd
[i
++]=swap_script(SCR_JUMP
^ IFTRUE (IF (SCR_DATA_OUT
))); /* data out ? */
526 script_cmd
[i
++]=swap_script(phys_to_bus(&script_data_out
[0]));
527 script_cmd
[i
++]=swap_script(SCR_JUMP
^ IFTRUE (IF (SCR_DATA_IN
))); /* data in ? */
528 script_cmd
[i
++]=swap_script(phys_to_bus(&script_data_in
[0]));
529 script_cmd
[i
++]=swap_script(SCR_JUMP
^ IFTRUE (IF (SCR_STATUS
))); /* status ? */
530 script_cmd
[i
++]=swap_script(phys_to_bus(&script_status
[0]));
531 script_cmd
[i
++]=swap_script(SCR_JUMP
^ IFTRUE (IF (SCR_COMMAND
))); /* command ? */
532 script_cmd
[i
++]=swap_script(phys_to_bus(&script_cmd
[0]));
533 script_cmd
[i
++]=swap_script(SCR_JUMP
^ IFTRUE (IF (SCR_MSG_OUT
))); /* message out ? */
534 script_cmd
[i
++]=swap_script(phys_to_bus(&script_msgout
[0]));
535 script_cmd
[i
++]=swap_script(SCR_JUMP
^ IFTRUE (IF (SCR_MSG_IN
))); /* just for error handling message in ? */
536 script_cmd
[i
++]=swap_script(phys_to_bus(&script_msgin
[0]));
537 script_cmd
[i
++]=swap_script(SCR_INT
); /* interrupt if not */
538 script_cmd
[i
++]=SIR_CMD_OUT_ILL_PH
;
539 #ifdef SCSI_SINGLE_STEP
540 start_script_cmd
=(unsigned long)&script_cmd
[0];
544 script_data_out
[i
++]=swap_script(SCR_MOVE_ABS(pccb
->datalen
)^ SCR_DATA_OUT
); /* move */
545 script_data_out
[i
++]=swap_script(phys_to_bus(pccb
->pdata
)); /* pointer to buffer */
546 script_data_out
[i
++]=swap_script(SCR_JUMP
^ IFTRUE (WHEN (SCR_STATUS
)));
547 script_data_out
[i
++]=swap_script(phys_to_bus(&script_status
[0]));
548 script_data_out
[i
++]=swap_script(SCR_INT
);
549 script_data_out
[i
++]=SIR_DATA_OUT_ERR
;
551 #ifdef SCSI_SINGLE_STEP
552 start_script_data_out
=(unsigned long)&script_data_out
[0];
553 len_script_data_out
=i
*4;
556 script_data_in
[i
++]=swap_script(SCR_MOVE_ABS(pccb
->datalen
)^ SCR_DATA_IN
); /* move */
557 script_data_in
[i
++]=swap_script(phys_to_bus(pccb
->pdata
)); /* pointer to buffer */
558 script_data_in
[i
++]=swap_script(SCR_JUMP
^ IFTRUE (WHEN (SCR_STATUS
)));
559 script_data_in
[i
++]=swap_script(phys_to_bus(&script_status
[0]));
560 script_data_in
[i
++]=swap_script(SCR_INT
);
561 script_data_in
[i
++]=SIR_DATA_IN_ERR
;
562 #ifdef SCSI_SINGLE_STEP
563 start_script_data_in
=(unsigned long)&script_data_in
[0];
564 len_script_data_in
=i
*4;
567 script_msgin
[i
++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN
);
568 script_msgin
[i
++]=swap_script(phys_to_bus(&pccb
->msgin
[0]));
569 script_msgin
[i
++]=swap_script(SCR_JUMP
^ IFTRUE (DATA (M_COMPLETE
)));
570 script_msgin
[i
++]=swap_script(phys_to_bus(&script_complete
[0]));
571 script_msgin
[i
++]=swap_script(SCR_JUMP
^ IFTRUE (DATA (M_DISCONNECT
)));
572 script_msgin
[i
++]=swap_script(phys_to_bus(&script_complete
[0]));
573 script_msgin
[i
++]=swap_script(SCR_JUMP
^ IFTRUE (DATA (M_SAVE_DP
)));
574 script_msgin
[i
++]=swap_script(phys_to_bus(&script_complete
[0]));
575 script_msgin
[i
++]=swap_script(SCR_JUMP
^ IFTRUE (DATA (M_RESTORE_DP
)));
576 script_msgin
[i
++]=swap_script(phys_to_bus(&script_complete
[0]));
577 script_msgin
[i
++]=swap_script(SCR_JUMP
^ IFTRUE (DATA (M_EXTENDED
)));
578 script_msgin
[i
++]=swap_script(phys_to_bus(&script_msg_ext
[0]));
579 script_msgin
[i
++]=swap_script(SCR_INT
);
580 script_msgin
[i
++]=SIR_MSG_RECEIVED
;
581 #ifdef SCSI_SINGLE_STEP
582 start_script_msgin
=(unsigned long)&script_msgin
[0];
583 len_script_msgin
=i
*4;
586 script_msg_ext
[i
++]=swap_script(SCR_CLR (SCR_ACK
)); /* clear ACK */
587 script_msg_ext
[i
++]=0;
588 script_msg_ext
[i
++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN
); /* assuming this is the msg length */
589 script_msg_ext
[i
++]=swap_script(phys_to_bus(&pccb
->msgin
[1]));
590 script_msg_ext
[i
++]=swap_script(SCR_JUMP
^ IFFALSE (IF (SCR_MSG_IN
)));
591 script_msg_ext
[i
++]=swap_script(phys_to_bus(&script_complete
[0])); /* no more bytes */
592 script_msg_ext
[i
++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN
); /* next */
593 script_msg_ext
[i
++]=swap_script(phys_to_bus(&pccb
->msgin
[2]));
594 script_msg_ext
[i
++]=swap_script(SCR_JUMP
^ IFFALSE (IF (SCR_MSG_IN
)));
595 script_msg_ext
[i
++]=swap_script(phys_to_bus(&script_complete
[0])); /* no more bytes */
596 script_msg_ext
[i
++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN
); /* next */
597 script_msg_ext
[i
++]=swap_script(phys_to_bus(&pccb
->msgin
[3]));
598 script_msg_ext
[i
++]=swap_script(SCR_JUMP
^ IFFALSE (IF (SCR_MSG_IN
)));
599 script_msg_ext
[i
++]=swap_script(phys_to_bus(&script_complete
[0])); /* no more bytes */
600 script_msg_ext
[i
++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN
); /* next */
601 script_msg_ext
[i
++]=swap_script(phys_to_bus(&pccb
->msgin
[4]));
602 script_msg_ext
[i
++]=swap_script(SCR_JUMP
^ IFFALSE (IF (SCR_MSG_IN
)));
603 script_msg_ext
[i
++]=swap_script(phys_to_bus(&script_complete
[0])); /* no more bytes */
604 script_msg_ext
[i
++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN
); /* next */
605 script_msg_ext
[i
++]=swap_script(phys_to_bus(&pccb
->msgin
[5]));
606 script_msg_ext
[i
++]=swap_script(SCR_JUMP
^ IFFALSE (IF (SCR_MSG_IN
)));
607 script_msg_ext
[i
++]=swap_script(phys_to_bus(&script_complete
[0])); /* no more bytes */
608 script_msg_ext
[i
++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN
); /* next */
609 script_msg_ext
[i
++]=swap_script(phys_to_bus(&pccb
->msgin
[6]));
610 script_msg_ext
[i
++]=swap_script(SCR_JUMP
^ IFFALSE (IF (SCR_MSG_IN
)));
611 script_msg_ext
[i
++]=swap_script(phys_to_bus(&script_complete
[0])); /* no more bytes */
612 script_msg_ext
[i
++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN
); /* next */
613 script_msg_ext
[i
++]=swap_script(phys_to_bus(&pccb
->msgin
[7]));
614 script_msg_ext
[i
++]=swap_script(SCR_JUMP
^ IFFALSE (IF (SCR_MSG_IN
)));
615 script_msg_ext
[i
++]=swap_script(phys_to_bus(&script_complete
[0])); /* no more bytes */
616 script_msg_ext
[i
++]=swap_script(SCR_INT
);
617 script_msg_ext
[i
++]=SIR_MSG_OVER7
;
618 #ifdef SCSI_SINGLE_STEP
619 start_script_msg_ext
=(unsigned long)&script_msg_ext
[0];
620 len_script_msg_ext
=i
*4;
623 script_status
[i
++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_STATUS
);
624 script_status
[i
++]=swap_script(phys_to_bus(&pccb
->status
));
625 script_status
[i
++]=swap_script(SCR_JUMP
^ IFTRUE (WHEN (SCR_MSG_IN
)));
626 script_status
[i
++]=swap_script(phys_to_bus(&script_msgin
[0]));
627 script_status
[i
++]=swap_script(SCR_INT
);
628 script_status
[i
++]=SIR_STATUS_ILL_PH
;
629 #ifdef SCSI_SINGLE_STEP
630 start_script_status
=(unsigned long)&script_status
[0];
631 len_script_status
=i
*4;
634 script_complete
[i
++]=swap_script(SCR_REG_REG (SCNTL2
, SCR_AND
, 0x7f));
635 script_complete
[i
++]=0;
636 script_complete
[i
++]=swap_script(SCR_CLR (SCR_ACK
|SCR_ATN
));
637 script_complete
[i
++]=0;
638 script_complete
[i
++]=swap_script(SCR_WAIT_DISC
);
639 script_complete
[i
++]=0;
640 script_complete
[i
++]=swap_script(SCR_REG_REG(GPREG
, SCR_OR
, 0x01));
641 script_complete
[i
++]=0; /* LED OFF */
642 script_complete
[i
++]=swap_script(SCR_INT
);
643 script_complete
[i
++]=SIR_COMPLETE
;
644 #ifdef SCSI_SINGLE_STEP
645 start_script_complete
=(unsigned long)&script_complete
[0];
646 len_script_complete
=i
*4;
649 script_error
[i
++]=swap_script(SCR_INT
); /* interrupt if error */
650 script_error
[i
++]=SIR_SCRIPT_ERROR
;
651 #ifdef SCSI_SINGLE_STEP
652 start_script_error
=(unsigned long)&script_error
[0];
653 len_script_error
=i
*4;
656 script_reselection
[i
++]=swap_script(SCR_CLR (SCR_TRG
)); /* target status */
657 script_reselection
[i
++]=0;
658 script_reselection
[i
++]=swap_script(SCR_WAIT_RESEL
);
659 script_reselection
[i
++]=swap_script(phys_to_bus(&script_select
[0])); /* len = 4 */
660 #ifdef SCSI_SINGLE_STEP
661 start_script_reselection
=(unsigned long)&script_reselection
[0];
662 len_script_reselection
=i
*4;
667 void scsi_issue(ccb
*pccb
)
669 int busdevfunc
= pccb
->priv
;
671 unsigned short sstat
;
672 int retrycnt
; /* retry counter */
674 int_stat
[i
]=0; /* delete all int status */
675 /* struct pccb must be set-up correctly */
677 PRINTF("ID %d issue cmd %02X\n",pccb
->target
,pccb
->cmd
[0]);
678 pccb
->trans_bytes
=0; /* no bytes transfered yet */
679 scsi_set_script(pccb
); /* fill in SCRIPT */
680 scsi_int_mask
=STO
| UDC
| MA
; /* | CMP; / * Interrupts which are enabled */
681 script_int_mask
=0xff; /* enable all Ints */
683 scsi_write_dsp(phys_to_bus(&script_select
[0])); /* start script */
684 /* now we have to wait for IRQs */
687 * This version of the driver is _not_ interrupt driven,
688 * but polls the chip's interrupt registers (ISTAT, DSTAT).
690 while(int_stat
[0]==0)
693 if(int_stat
[0]==SIR_COMPLETE
) {
694 if(pccb
->msgin
[0]==M_DISCONNECT
) {
695 PRINTF("Wait for reselection\n");
697 int_stat
[i
]=0; /* delete all int status */
698 scsi_write_dsp(phys_to_bus(&script_reselection
[0])); /* start reselection script */
701 pccb
->contr_stat
=SIR_COMPLETE
;
704 if((int_stat
[0] & SCSI_INT_STATE
)==SCSI_INT_STATE
) { /* scsi interrupt */
705 sstat
=(unsigned short)int_stat
[0];
706 if((sstat
& STO
)==STO
) { /* selection timeout */
707 pccb
->contr_stat
=SCSI_SEL_TIME_OUT
;
708 scsi_write_byte(GPREG
,0x01);
709 PRINTF("ID: %X Selection Timeout\n",pccb
->target
);
712 if((sstat
& UDC
)==UDC
) { /* unexpected disconnect */
713 pccb
->contr_stat
=SCSI_UNEXP_DIS
;
714 scsi_write_byte(GPREG
,0x01);
715 PRINTF("ID: %X Unexpected Disconnect\n",pccb
->target
);
718 if((sstat
& RSL
)==RSL
) { /* reselection */
719 pccb
->contr_stat
=SCSI_UNEXP_DIS
;
720 scsi_write_byte(GPREG
,0x01);
721 PRINTF("ID: %X Unexpected Disconnect\n",pccb
->target
);
724 if(((sstat
& MA
)==MA
)||((sstat
& HTH
)==HTH
)) { /* phase missmatch */
725 if(retrycnt
<SCSI_MAX_RETRY
) {
726 pccb
->trans_bytes
=pccb
->datalen
-
727 ((unsigned long)scsi_read_byte(DBC
) |
728 ((unsigned long)scsi_read_byte(DBC
+1)<<8) |
729 ((unsigned long)scsi_read_byte(DBC
+2)<<16));
731 int_stat
[i
]=0; /* delete all int status */
733 PRINTF("ID: %X Phase Missmatch Retry %d Phase %02X transfered %lx\n",
734 pccb
->target
,retrycnt
,scsi_read_byte(SBCL
),pccb
->trans_bytes
);
735 scsi_write_dsp(phys_to_bus(&script_cmd
[4])); /* start retry script */
739 pccb
->contr_stat
=SCSI_MA_TIME_OUT
;
741 pccb
->contr_stat
=SCSI_HNS_TIME_OUT
;
742 PRINTF("Phase Missmatch stat %lx\n",pccb
->contr_stat
);
745 /* if((sstat & CMP)==CMP) {
746 pccb->contr_stat=SIR_COMPLETE;
750 PRINTF("SCSI INT %lX\n",int_stat
[0]);
751 pccb
->contr_stat
=int_stat
[0];
754 PRINTF("SCRIPT INT %lX phase %02X\n",int_stat
[0],scsi_read_byte(SBCL
));
755 pccb
->contr_stat
=int_stat
[0];
759 int scsi_exec(ccb
*pccb
)
761 unsigned char tmpcmd
[16],tmpstat
;
763 unsigned long transbytes
,datalen
;
764 unsigned char *tmpptr
;
768 if(pccb
->contr_stat
!=SIR_COMPLETE
)
770 if(pccb
->status
==S_GOOD
)
772 if(pccb
->status
==S_CHECK_COND
) { /* check condition */
774 tmpcmd
[i
]=pccb
->cmd
[i
];
775 pccb
->cmd
[0]=SCSI_REQ_SENSE
;
776 pccb
->cmd
[1]=pccb
->lun
<<5;
782 pccb
->msgout
[0]=SCSI_IDENTIFY
;
783 transbytes
=pccb
->trans_bytes
;
785 pccb
->pdata
= &pccb
->sense_buf
[0];
786 datalen
=pccb
->datalen
;
788 tmpstat
=pccb
->status
;
791 pccb
->cmd
[i
]=tmpcmd
[i
];
792 pccb
->trans_bytes
=transbytes
;
794 pccb
->datalen
=datalen
;
795 pccb
->status
=tmpstat
;
796 PRINTF("Request_sense sense key %x ASC %x ASCQ %x\n",pccb
->sense_buf
[2]&0x0f,
797 pccb
->sense_buf
[12],pccb
->sense_buf
[13]);
798 switch(pccb
->sense_buf
[2]&0xf) {
800 case SENSE_RECOVERED_ERROR
:
804 case SENSE_NOT_READY
:
805 if((pccb
->sense_buf
[12]!=0x04)||(pccb
->sense_buf
[13]!=0x01)) {
806 /* if device is not in process of becoming ready */
809 } /* else fall through */
810 case SENSE_UNIT_ATTENTION
:
811 if(retrycnt
<SCSI_MAX_RETRY_NOT_READY
) {
812 PRINTF("Target %d not ready, retry %d\n",pccb
->target
,retrycnt
);
813 for(t
=0;t
<SCSI_NOT_READY_TIME_OUT
;t
++)
814 udelay(1000); /* 1sec wait */
818 PRINTF("Target %d not ready, %d retried\n",pccb
->target
,retrycnt
);
824 PRINTF("Status = %X\n",pccb
->status
);
829 void scsi_chip_init(void)
831 /* first we issue a soft reset */
832 scsi_write_byte(ISTAT
,SRST
);
834 scsi_write_byte(ISTAT
,0);
836 scsi_write_byte(SCNTL0
,0xC0); /* full arbitration no start, no message, parity disabled, master */
837 scsi_write_byte(SCNTL1
,0x00);
838 scsi_write_byte(SCNTL2
,0x00);
839 #ifndef CFG_SCSI_SYM53C8XX_CCF /* config value for none 40 mhz clocks */
840 scsi_write_byte(SCNTL3
,0x13); /* synchronous clock 40/4=10MHz, asynchronous 40MHz */
842 scsi_write_byte(SCNTL3
,CFG_SCSI_SYM53C8XX_CCF
); /* config value for none 40 mhz clocks */
844 scsi_write_byte(SCID
,0x47); /* ID=7, enable reselection */
845 scsi_write_byte(SXFER
,0x00); /* synchronous transfer period 10MHz, asynchronous */
846 scsi_write_byte(SDID
,0x00); /* targed SCSI ID = 0 */
847 scsi_int_mask
=0x0000; /* no Interrupt is enabled */
848 script_int_mask
=0x00;
850 scsi_write_byte(GPREG
,0x01); /* GPIO0 is LED (off) */
851 scsi_write_byte(GPCNTL
,0x0E); /* GPIO0 is Output */
852 scsi_write_byte(STIME0
,0x08); /* handshake timer disabled, selection timeout 512msec */
853 scsi_write_byte(RESPID
,0x80); /* repond only to the own ID (reselection) */
854 scsi_write_byte(STEST1
,0x00); /* not isolated, SCLK is used */
855 scsi_write_byte(STEST2
,0x00); /* no Lowlevel Mode? */
856 scsi_write_byte(STEST3
,0x80); /* enable tolerANT */
857 scsi_write_byte(CTEST3
,0x04); /* clear FIFO */
858 scsi_write_byte(CTEST4
,0x00);
859 scsi_write_byte(CTEST5
,0x00);
860 #ifdef SCSI_SINGLE_STEP
861 /* scsi_write_byte(DCNTL,IRQM | SSM); */
862 scsi_write_byte(DCNTL
,IRQD
| SSM
);
863 scsi_write_byte(DMODE
,MAN
);
865 /* scsi_write_byte(DCNTL,IRQM); */
866 scsi_write_byte(DCNTL
,IRQD
);
867 scsi_write_byte(DMODE
,0x00);