2 * sim710.c - Copyright (C) 1999 Richard Hirst <richard@sleepie.demon.co.uk>
4 *----------------------------------------------------------------------------
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 *----------------------------------------------------------------------------
20 * MCA card detection code by Trent McNair.
22 * Various bits of code in this driver have been copied from 53c7,8xx,c,
23 * which is coyright Drew Eckhardt. The scripts for the SCSI chip are
24 * compiled with the script compiler written by Drew.
26 * This is a simple driver for the NCR53c710. More complex drivers
27 * for this chip (e.g. 53c7xx.c) require that the scsi chip be able to
28 * do DMA block moves between memory and on-chip registers, which can
29 * be a problem if those registers are in the I/O address space. There
30 * can also be problems on hardware where the registers are memory
31 * mapped, if the design is such that memory-to-memory transfers initiated
32 * by the scsi chip cannot access the chip registers.
34 * This driver is designed to avoid these problems and is intended to
35 * work with any Intel machines using 53c710 chips, including various
36 * Compaq and NCR machines. It was initially written for the Tadpole
37 * TP34V VME board which is 68030 based.
39 * The driver supports boot-time parameters similar to
40 * sim710=addr:0x9000,irq:15
41 * and insmod parameters similar to
42 * sim710="addr:0x9000 irq:15"
44 * The complete list of options are:
46 * addr:0x9000 Specifies the base I/O port (or address) of the 53C710.
47 * irq:15 Specifies the IRQ number used by the 53c710.
48 * debug:0xffff Generates lots of debug output.
49 * ignore:0x0a Makes the driver ignore SCSI IDs 0 and 2.
50 * nodisc:0x70 Prevents disconnects from IDs 6, 5 and 4.
51 * noneg:0x10 Prevents SDTR negotiation on ID 4.
53 * Current limitations:
56 * o Severely lacking in error recovery
57 * o Auto detection of IRQs and chip addresses only on MCA architectures
61 #define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
63 #include <linux/config.h>
64 #include <linux/module.h>
66 #include <linux/kernel.h>
67 #include <linux/types.h>
68 #include <linux/string.h>
69 #include <linux/ioport.h>
70 #include <linux/delay.h>
71 #include <linux/sched.h>
72 #include <linux/proc_fs.h>
73 #include <linux/init.h>
74 #include <linux/mca.h>
76 #include <asm/system.h>
77 #if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,17)
78 #include <linux/spinlock.h>
79 #elif LINUX_VERSION_CODE >= LinuxVersionCode(2,1,93)
80 #include <asm/spinlock.h>
83 #include <asm/pgtable.h>
84 #include <asm/byteorder.h>
85 #include <linux/blk.h>
87 #ifdef CONFIG_TP34V_SCSI
89 #include <asm/tp34vhw.h>
92 #elif defined(CONFIG_MCA)
97 * For each known microchannel card using the 53c710 we need a list
98 * of possible IRQ and IO settings, as well as their corresponding
99 * bit assignment in pos[]. This might get cumbersome if there
100 * are more than a few cards (I only know of 2 at this point).
103 #define MCA_53C710_IDS { 0x01bb, 0x01ba, 0x004f }
105 /* CARD ID 01BB and 01BA use the same pos values */
107 #define MCA_01BB_IO_PORTS { 0x0000, 0x0000, 0x0800, 0x0C00, 0x1000, 0x1400, \
108 0x1800, 0x1C00, 0x2000, 0x2400, 0x2800, \
109 0x2C00, 0x3000, 0x3400, 0x3800, 0x3C00, \
110 0x4000, 0x4400, 0x4800, 0x4C00, 0x5000 }
112 #define MCA_01BB_IRQS { 3, 5, 11, 14 }
116 #define MCA_004F_IO_PORTS { 0x0000, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600 }
118 #define MCA_004F_IRQS { 5, 9, 14 }
122 /* Assume an Intel platform */
132 #include<linux/stat.h>
135 #undef DEBUG_LIMIT_INTS /* Define to 10 to hang driver after 10 ints */
137 /* Debug options available via the "debug:0x1234" parameter */
139 #define DEB_NONE 0x0000 /* Nothing */
140 #define DEB_HALT 0x0001 /* Detailed trace of chip halt funtion */
141 #define DEB_REGS 0x0002 /* All chip register read/writes */
142 #define DEB_SYNC 0x0004 /* Sync/async negotiation */
143 #define DEB_PMM 0x0008 /* Phase mis-match handling */
144 #define DEB_INTS 0x0010 /* General interrupt trace */
145 #define DEB_TOUT 0x0020 /* Selection timeouts */
146 #define DEB_RESUME 0x0040 /* Resume addresses for the script */
147 #define DEB_CMND 0x0080 /* Commands and status returned */
148 #define DEB_FIXUP 0x0100 /* Fixup of scsi addresses */
149 #define DEB_DISC 0x0200 /* Disconnect/reselect handling */
151 #define DEB_ANY 0xffff /* Any and all debug options */
154 #define DEB(m,x) if (sim710_debug & m) x
155 int sim710_debug
= 0;
160 /* Redefine scsi_done to force renegotiation of (a)sync transfers
161 * following any failed command.
164 #define SCSI_DONE(cmd) { \
165 DEB(DEB_CMND, printk("scsi%d: Complete %08x\n", \
166 host->host_no, cmd->result)); \
168 hostdata->negotiate |= (1 << cmd->target); \
169 cmd->scsi_done(cmd); \
173 #define offsetof(t, m) ((size_t) (&((t *)0)->m))
176 #define STATE_INITIALISED 0
177 #define STATE_HALTED 1
180 #define STATE_DISABLED 4
182 #define MAXBOARDS 2 /* Increase this and the sizes of the
183 arrays below, if you need more.. */
187 char *sim710
; /* command line passed by insmod */
189 MODULE_AUTHOR("Richard Hirst");
190 MODULE_DESCRIPTION("Simple NCR53C710 driver");
191 MODULE_PARM(sim710
, "s");
195 static int sim710_errors
= 0; /* Count of error interrupts */
196 static int sim710_intrs
= 0; /* Count of all interrupts */
197 static int ignore_ids
= 0; /* Accept all SCSI IDs */
198 static int opt_nodisc
= 0; /* Allow disconnect on all IDs */
199 static int opt_noneg
= 0; /* Allow SDTR negotiation on all IDs */
201 #ifdef CONFIG_TP34V_SCSI
203 /* Special hardwired case for Tadpole TP34V at the moment, otherwise
204 * boot parameters 'sim710=addr:0x8000,irq:15' (for example) must be given.
207 static int no_of_boards
= 2;
209 static unsigned int bases
[MAXBOARDS
] = {
210 TP34V_SCSI0_BASE
, TP34V_SCSI1_BASE
212 static unsigned int irq_vectors
[MAXBOARDS
] = {
213 TP34V_SCSI0_VECTOR
, TP34V_SCSI1_VECTOR
215 static unsigned int irq_index
[MAXBOARDS
] = {
216 TP34V_SCSI0_IRQ_INDEX
, TP34V_SCSI1_IRQ_INDEX
221 /* All other cases use boot/module params, or auto-detect */
223 static int no_of_boards
= 0;
225 static unsigned int bases
[MAXBOARDS
] = {
228 static unsigned int irq_vectors
[MAXBOARDS
] = {
234 /* The SCSI Script!!! */
236 #include "sim710_d.h"
238 /* Now define offsets in the DSA, as (A_dsa_xxx/4) */
240 #define DSA_SELECT (A_dsa_select/4)
241 #define DSA_MSGOUT (A_dsa_msgout/4)
242 #define DSA_CMND (A_dsa_cmnd/4)
243 #define DSA_STATUS (A_dsa_status/4)
244 #define DSA_MSGIN (A_dsa_msgin/4)
245 #define DSA_DATAIN (A_dsa_datain/4)
246 #define DSA_DATAOUT (A_dsa_dataout/4)
247 #define DSA_SIZE (A_dsa_size/4)
249 #define MAX_SG 128 /* Scatter/Gather elements */
257 struct sim710_hostdata
{
259 Scsi_Cmnd
* issue_queue
;
263 u8 reselected_identify
;
264 u8 msgin_buf
[MAX_MSGIN
];
266 struct sim710_target
{
271 u32 dsa
[DSA_SIZE
]; /* SCSI Script DSA area */
272 u8 dsa_msgout
[MAX_MSGOUT
];
273 u8 dsa_msgin
[MAX_MSGIN
];
274 u8 dsa_cdb
[MAX_CMND
];
275 u8 dsa_status
[MAX_STATUS
];
278 u32 script
[sizeof(SCRIPT
)/4] __attribute__ ((aligned (4)));
282 /* Template to request asynchronous transfers */
284 static const unsigned char async_message
[] = {
285 EXTENDED_MESSAGE
, 3 /* length */, EXTENDED_SDTR
, 0, 0 /* asynchronous */};
288 static void sim710_intr_handle(int irq
, void *dev_id
, struct pt_regs
*regs
);
289 static void do_sim710_intr_handle(int irq
, void *dev_id
, struct pt_regs
*regs
);
290 static __inline__
void run_process_issue_queue(struct sim710_hostdata
*);
291 static void process_issue_queue (struct sim710_hostdata
*, unsigned long flags
);
292 static int full_reset(struct Scsi_Host
* host
);
295 * Function: void sim710_setup(char *str, int *ints)
305 sim710_setup(char *str
, int *ints
)
314 while (cur
!= NULL
&& (pc
= strchr(cur
, ':')) != NULL
) {
327 val
= (int) simple_strtoul(pv
, &pe
, base
);
329 if (!strncmp(cur
, "addr:", 5)) {
333 else if (!strncmp(cur
, "irq:", 4))
334 irq_vectors
[0] = val
;
335 else if (!strncmp(cur
, "ignore:", 7))
337 else if (!strncmp(cur
, "nodisc:", 7))
339 else if (!strncmp(cur
, "noneg:", 6))
341 else if (!strncmp(cur
, "disabled:", 5)) {
346 else if (!strncmp(cur
, "debug:", 6)) {
351 printk("sim710_setup: unexpected boot option '%.*s' ignored\n", (int)(pc
-cur
+1), cur
);
353 if ((cur
= strchr(cur
, ARG_SEP
)) != NULL
)
358 #if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,13)
360 __setup("sim710=", sim710_setup
);
365 * Function: static const char *sbcl_to_phase (int sbcl)
369 sbcl_to_phase (int sbcl
) {
370 switch (sbcl
& SBCL_PHASE_MASK
) {
371 case SBCL_PHASE_DATAIN
:
373 case SBCL_PHASE_DATAOUT
:
375 case SBCL_PHASE_MSGIN
:
377 case SBCL_PHASE_MSGOUT
:
379 case SBCL_PHASE_CMDOUT
:
381 case SBCL_PHASE_STATIN
:
390 * Function: static void disable (struct Scsi_Host *host)
394 disable (struct Scsi_Host
*host
)
396 struct sim710_hostdata
*hostdata
= (struct sim710_hostdata
*)
399 hostdata
->state
= STATE_DISABLED
;
400 printk (KERN_ALERT
"scsi%d : disabled. Unload and reload\n",
406 * Function : static int ncr_halt (struct Scsi_Host *host)
408 * Purpose : halts the SCSI SCRIPTS(tm) processor on the NCR chip
410 * Inputs : host - SCSI chip to halt
412 * Returns : 0 on success
416 ncr_halt (struct Scsi_Host
*host
)
419 unsigned char istat
, tmp
;
420 struct sim710_hostdata
*hostdata
= (struct sim710_hostdata
*)
426 /* Stage 0 : eat all interrupts
428 Stage 2 : eat all but abort interrupts
429 Stage 3 : eat all interrupts
433 DEB(DEB_HALT
, printk("ncr_halt: writing ISTAT_ABRT\n"));
434 NCR_write8(ISTAT_REG
, ISTAT_ABRT
);
437 istat
= NCR_read8 (ISTAT_REG
);
438 if (istat
& ISTAT_SIP
) {
439 DEB(DEB_HALT
, printk("ncr_halt: got ISTAT_SIP, istat=%02x\n", istat
));
440 tmp
= NCR_read8(SSTAT0_REG
);
441 DEB(DEB_HALT
, printk("ncr_halt: got SSTAT0_REG=%02x\n", tmp
));
442 } else if (istat
& ISTAT_DIP
) {
443 DEB(DEB_HALT
, printk("ncr_halt: got ISTAT_DIP, istat=%02x\n", istat
));
444 tmp
= NCR_read8(DSTAT_REG
);
445 DEB(DEB_HALT
, printk("ncr_halt: got DSTAT_REG=%02x\n", tmp
));
447 if (tmp
& DSTAT_ABRT
) {
448 DEB(DEB_HALT
, printk("ncr_halt: got DSTAT_ABRT, clearing istat\n"));
449 NCR_write8(ISTAT_REG
, 0);
452 printk(KERN_ALERT
"scsi%d : could not halt NCR chip\n",
458 if (!(istat
& (ISTAT_SIP
|ISTAT_DIP
))) {
465 hostdata
->state
= STATE_HALTED
;
466 restore_flags(flags
);
471 * Function : static void sim710_soft_reset (struct Scsi_Host *host)
473 * Purpose : perform a soft reset of the NCR53c7xx chip
475 * Inputs : host - pointer to this host adapter's structure
477 * Preconditions : sim710_init must have been called for this
483 sim710_soft_reset (struct Scsi_Host
*host
)
486 #ifdef CONFIG_TP34V_SCSI
487 struct sim710_hostdata
*hostdata
= (struct sim710_hostdata
*)
493 #ifdef CONFIG_TP34V_SCSI
494 tpvic
.loc_icr
[irq_index
[hostdata
->chip
]].icr
= 0x80;
497 * Do a soft reset of the chip so that everything is
498 * reinitialized to the power-on state.
500 * Basically follow the procedure outlined in the NCR53c700
501 * data manual under Chapter Six, How to Use, Steps Necessary to
502 * Start SCRIPTS, with the exception of actually starting the
503 * script and setting up the synchronous transfer gunk.
506 /* XXX Should we reset the scsi bus here? */
508 NCR_write8(SCNTL1_REG
, SCNTL1_RST
); /* Reset the bus */
510 NCR_write8(SCNTL1_REG
, 0);
514 NCR_write8(ISTAT_REG
, ISTAT_10_SRST
); /* Reset the chip */
516 NCR_write8(ISTAT_REG
, 0);
518 mdelay(1000); /* Let devices recover */
520 NCR_write8(DCNTL_REG
, DCNTL_10_COM
| DCNTL_700_CF_3
);
521 NCR_write8(CTEST7_REG
, CTEST7_10_CDIS
|CTEST7_STD
);
522 NCR_write8(DMODE_REG
, DMODE_10_BL_8
| DMODE_10_FC2
);
523 NCR_write8(SCID_REG
, 1 << host
->this_id
);
524 NCR_write8(SBCL_REG
, 0);
525 NCR_write8(SXFER_REG
, 0);
526 NCR_write8(SCNTL1_REG
, SCNTL1_ESR_700
);
527 NCR_write8(SCNTL0_REG
, SCNTL0_EPC
| SCNTL0_EPG_700
| SCNTL0_ARB1
|
530 NCR_write8(DIEN_REG
, DIEN_700_BF
|
531 DIEN_ABRT
| DIEN_SSI
| DIEN_SIR
| DIEN_700_OPC
);
533 NCR_write8(SIEN_REG_700
,
534 SIEN_PAR
| SIEN_700_STO
| SIEN_RST
| SIEN_UDC
| SIEN_SGE
| SIEN_MA
);
537 #ifdef CONFIG_TP34V_SCSI
538 tpvic
.loc_icr
[irq_index
[hostdata
->chip
]].icr
= 0x30 | TP34V_SCSI0n1_IPL
;
541 restore_flags(flags
);
546 * Function : static void sim710_driver_init (struct Scsi_Host *host)
548 * Purpose : Initialize internal structures, as required on startup, or
549 * after a SCSI bus reset.
551 * Inputs : host - pointer to this host adapter's structure
555 sim710_driver_init (struct Scsi_Host
*host
)
557 struct sim710_hostdata
*hostdata
= (struct sim710_hostdata
*)
561 hostdata
->running
= NULL
;
562 memcpy (hostdata
->script
, SCRIPT
, sizeof(SCRIPT
));
563 for (i
= 0; i
< PATCHES
; i
++)
564 hostdata
->script
[LABELPATCHES
[i
]] += virt_to_bus(hostdata
->script
);
565 patch_abs_32 (hostdata
->script
, 0, reselected_identify
,
566 virt_to_bus((void *)&(hostdata
->reselected_identify
)));
567 patch_abs_32 (hostdata
->script
, 0, msgin_buf
,
568 virt_to_bus((void *)&(hostdata
->msgin_buf
[0])));
569 hostdata
->state
= STATE_INITIALISED
;
570 hostdata
->negotiate
= 0xff;
574 /* Handle incoming Synchronous data transfer request. If our negotiate
575 * flag is set then this is a response to our request, otherwise it is
576 * spurious request from the target. Don't really expect target initiated
577 * SDTRs, because we always negotiate on the first command. Could still
579 * The chip is currently paused with ACK asserted o the last byte of the
581 * resa is the resume address if the message is in response to our outgoing
582 * SDTR. Only possible on initial identify.
583 * resb is the resume address if the message exchange is initiated by the
588 handle_sdtr (struct Scsi_Host
* host
, Scsi_Cmnd
* cmd
, u32 resa
, u32 resb
)
590 struct sim710_hostdata
*hostdata
= (struct sim710_hostdata
*)host
->hostdata
[0];
591 struct sim710_target
*targdata
= hostdata
->target
+ cmd
->target
;
594 if (resa
&& hostdata
->negotiate
& (1 << cmd
->target
)) {
595 DEB(DEB_SYNC
, printk("scsi%d: Response to host SDTR = %02x %02x\n",
596 host
->host_no
, hostdata
->msgin_buf
[3], hostdata
->msgin_buf
[4]));
597 /* We always issue an SDTR with the identify, so we must issue
600 resume_offset
= resa
;
601 hostdata
->negotiate
&= ~(1 << cmd
->target
);
604 DEB(DEB_SYNC
, printk("scsi%d: Target initiated SDTR = %02x %02x\n",
605 host
->host_no
, hostdata
->msgin_buf
[3], hostdata
->msgin_buf
[4]));
606 memcpy(targdata
->dsa_msgout
, async_message
, sizeof(async_message
));
607 targdata
->dsa
[DSA_MSGOUT
] = sizeof(async_message
);
608 /* I guess the target could do this anytime; we have to send our
609 * response, and then continue (sending the CDB if not already done).
611 resume_offset
= resb
;
613 return resume_offset
;
618 * Function : static int datapath_residual (Scsi_Host *host)
620 * Purpose : return residual data count of what's in the chip.
622 * Inputs : host - SCSI host
626 datapath_residual (struct Scsi_Host
*host
) {
627 int count
, synchronous
, sstat
;
630 count
= ((NCR_read8 (DFIFO_REG
) & DFIFO_10_BO_MASK
) -
631 (NCR_read32 (DBC_REG
) & DFIFO_10_BO_MASK
)) & DFIFO_10_BO_MASK
;
632 synchronous
= NCR_read8 (SXFER_REG
) & SXFER_MO_MASK
;
633 ddir
= NCR_read8 (CTEST0_REG_700
) & CTEST0_700_DDIR
;
638 count
+= (NCR_read8 (SSTAT2_REG
) & SSTAT2_FF_MASK
) >> SSTAT2_FF_SHIFT
;
640 if (NCR_read8 (SSTAT1_REG
) & SSTAT1_ILF
)
644 sstat
= NCR_read8 (SSTAT1_REG
);
645 if (sstat
& SSTAT1_OLF
)
647 if (synchronous
&& (sstat
& SSTAT1_ORF
))
655 handle_idd (struct Scsi_Host
* host
, Scsi_Cmnd
* cmd
)
657 struct sim710_hostdata
*hostdata
=
658 (struct sim710_hostdata
*)host
->hostdata
[0];
659 struct sim710_target
*targdata
= hostdata
->target
+ cmd
->target
;
660 u32 resume_offset
= 0, index
;
662 index
= (u32
)((u32
*)(bus_to_virt(NCR_read32(DSP_REG
))) - hostdata
->script
);
665 case Ent_wait_disc_complete
/4 + 2:
666 cmd
->result
= targdata
->dsa_status
[0];
668 targdata
->cur_cmd
= NULL
;
669 resume_offset
= Ent_reselect
;
671 case Ent_wait_disc2
/4 + 2:
672 /* Disconnect after command - just wait for a reselect */
673 targdata
->resume_offset
= Ent_resume_msgin2a
;
674 resume_offset
= Ent_reselect
;
676 case Ent_wait_disc3
/4 + 2:
677 /* Disconnect after the data phase */
678 targdata
->resume_offset
= Ent_resume_msgin3a
;
679 resume_offset
= Ent_reselect
;
681 case Ent_wait_disc1
/4 + 2:
682 /* Disconnect before command - not expected */
683 targdata
->resume_offset
= Ent_resume_msgin1a
;
684 resume_offset
= Ent_reselect
;
687 printk("scsi%d: Unexpected Illegal Instruction, script[%04x]\n",
688 host
->host_no
, index
);
690 /* resume_offset is zero, which will cause host reset */
692 return resume_offset
;
696 /* Handle a phase mismatch.
700 handle_phase_mismatch (struct Scsi_Host
* host
, Scsi_Cmnd
* cmd
)
702 struct sim710_hostdata
*hostdata
=
703 (struct sim710_hostdata
*)host
->hostdata
[0];
704 struct sim710_target
*targdata
= hostdata
->target
+ cmd
->target
;
705 u32 resume_offset
= 0, index
;
708 sbcl
= NCR_read8(SBCL_REG
) & SBCL_PHASE_MASK
;
709 index
= (u32
)((u32
*)(bus_to_virt(NCR_read32(DSP_REG
))) - hostdata
->script
);
711 DEB(DEB_PMM
, printk("scsi%d: Phase mismatch, phase %s (%x) at script[0x%x]\n",
712 host
->host_no
, sbcl_to_phase(sbcl
), sbcl
, index
));
713 DEB(DEB_PMM
, print_command(cmd
->cmnd
));
715 if (index
== Ent_done_ident
/4) {
716 /* Sending initial message out - probably rejecting our sync
717 * negotiation request.
719 NCR_write8(SOCL_REG
, 0); /* Negate ATN */
720 if (sbcl
== SBCL_PHASE_MSGIN
)
721 resume_offset
= Ent_resume_rej_ident
;
722 else if (sbcl
== SBCL_PHASE_CMDOUT
) {
723 /* Some old devices (SQ555) switch to cmdout after the first
724 * byte of an identify message, regardless of whether we
725 * have more bytes to send!
727 printk("scsi%d: Unexpected switch to CMDOUT during IDENTIFY\n",
729 resume_offset
= Ent_resume_cmd
;
732 printk("scsi%d: Unexpected phase change to %s on initial msgout\n",
733 host
->host_no
, sbcl_to_phase(sbcl
));
734 /* resume_offset is zero, which will cause a host reset */
736 hostdata
->negotiate
&= ~(1 << cmd
->target
);
738 else if (index
> Ent_patch_input_data
/4 &&
739 index
< Ent_patch_output_data
/4) {
740 /* DataIn transfer phase */
741 u32 sg_id
, oaddr
, olen
, naddr
, nlen
;
744 sg_id
= (index
- Ent_patch_input_data
/4 - 4) / 2;
745 targdata
->data_in_jump
= hostdata
->script
[Ent_patch_input_data
/4+1] =
746 virt_to_bus(hostdata
->script
+ Ent_patch_input_data
/4 + sg_id
* 2 + 2);
747 olen
= targdata
->dsa
[DSA_DATAIN
+ sg_id
* 2];
748 oaddr
= targdata
->dsa
[DSA_DATAIN
+ sg_id
* 2 + 1];
749 residual
= datapath_residual (host
);
751 printk("scsi%d: Residual count %d on DataIn - NOT expected!!!",
752 host
->host_no
, residual
);
753 naddr
= NCR_read32(DNAD_REG
) - residual
;
754 nlen
= (NCR_read32(DBC_REG
) & 0x00ffffff) + residual
;
755 DEB(DEB_PMM
, printk("scsi%d: DIN sg %d, old %08x/%08x, new %08x/%08x (%d)\n",
756 host
->host_no
, sg_id
, oaddr
, olen
, naddr
, nlen
, residual
));
757 if (oaddr
+olen
!= naddr
+nlen
) {
758 printk("scsi%d: PMM DIN counts error: 0x%x + 0x%x != 0x%x + 0x%x",
759 host
->host_no
, oaddr
, olen
, naddr
, nlen
);
762 targdata
->dsa
[DSA_DATAIN
+ sg_id
* 2] = nlen
;
763 targdata
->dsa
[DSA_DATAIN
+ sg_id
* 2 + 1] = naddr
;
764 resume_offset
= Ent_resume_pmm
;
767 else if (index
> Ent_patch_output_data
/4 &&
768 index
<= Ent_end_data_trans
/4) {
769 /* Dataout transfer phase */
770 u32 sg_id
, oaddr
, olen
, naddr
, nlen
;
773 sg_id
= (index
- Ent_patch_output_data
/4 - 4) / 2;
774 targdata
->data_out_jump
= hostdata
->script
[Ent_patch_output_data
/4+1] =
775 virt_to_bus(hostdata
->script
+ Ent_patch_output_data
/4 + sg_id
* 2 + 2);
776 olen
= targdata
->dsa
[DSA_DATAOUT
+ sg_id
* 2];
777 oaddr
= targdata
->dsa
[DSA_DATAOUT
+ sg_id
* 2 + 1];
778 residual
= datapath_residual (host
);
779 naddr
= NCR_read32(DNAD_REG
) - residual
;
780 nlen
= (NCR_read32(DBC_REG
) & 0x00ffffff) + residual
;
781 DEB(DEB_PMM
, printk("scsi%d: DOUT sg %d, old %08x/%08x, new %08x/%08x (%d)\n",
782 host
->host_no
, sg_id
, oaddr
, olen
, naddr
, nlen
, residual
));
783 if (oaddr
+olen
!= naddr
+nlen
) {
784 printk("scsi%d: PMM DOUT counts error: 0x%x + 0x%x != 0x%x + 0x%x",
785 host
->host_no
, oaddr
, olen
, naddr
, nlen
);
788 targdata
->dsa
[DSA_DATAOUT
+ sg_id
* 2] = nlen
;
789 targdata
->dsa
[DSA_DATAOUT
+ sg_id
* 2 + 1] = naddr
;
790 resume_offset
= Ent_resume_pmm
;
794 printk("scsi%d: Unexpected phase change to %s at index 0x%x\n",
795 host
->host_no
, sbcl_to_phase(sbcl
), index
);
796 /* resume_offset is zero, which will cause a host reset */
799 NCR_write8 (CTEST8_REG
, CTEST8_10_CLF
);
800 while (NCR_read8 (CTEST8_REG
) & CTEST8_10_CLF
);
802 return resume_offset
;
807 handle_script_int(struct Scsi_Host
* host
, Scsi_Cmnd
* cmd
)
809 struct sim710_hostdata
*hostdata
=
810 (struct sim710_hostdata
*)host
->hostdata
[0];
811 struct sim710_target
*targdata
= hostdata
->target
+ cmd
->target
;
812 u32 dsps
, resume_offset
= 0;
815 dsps
= NCR_read32(DSPS_REG
);
818 case A_int_cmd_complete
:
819 cmd
->result
= targdata
->dsa_status
[0];
821 targdata
->cur_cmd
= NULL
;
822 resume_offset
= Ent_reselect
;
824 case A_int_msg_sdtr1
:
825 resume_offset
= handle_sdtr(host
, cmd
,
826 Ent_resume_msgin1a
, Ent_resume_msgin1b
);
828 case A_int_msg_sdtr2
:
829 resume_offset
= handle_sdtr(host
, cmd
, 0, Ent_resume_msgin2b
);
831 case A_int_msg_sdtr3
:
832 resume_offset
= handle_sdtr(host
, cmd
, 0, Ent_resume_msgin3b
);
835 /* Disconnect before command - not expected */
836 targdata
->resume_offset
= Ent_resume_msgin1a
;
837 resume_offset
= Ent_reselect
;
840 /* Disconnect after command - just wait for a reselect */
841 targdata
->resume_offset
= Ent_resume_msgin2a
;
842 resume_offset
= Ent_reselect
;
845 /* Disconnect after the data phase */
846 targdata
->resume_offset
= Ent_resume_msgin3a
;
847 resume_offset
= Ent_reselect
;
849 case A_int_reselected
:
850 hostdata
->script
[Ent_patch_output_data
/4+1] = targdata
->data_out_jump
;
851 hostdata
->script
[Ent_patch_input_data
/4+1] = targdata
->data_in_jump
;
852 NCR_write32(DSA_REG
, virt_to_bus(targdata
->dsa
));
853 resume_offset
= targdata
->resume_offset
;
855 case A_int_data_bad_phase
:
856 sbcl
= NCR_read8(SBCL_REG
) & SBCL_PHASE_MASK
;
857 printk("scsi%d: int_data_bad_phase, phase %s (%x)\n",
858 host
->host_no
, sbcl_to_phase(sbcl
), sbcl
);
860 case A_int_bad_extmsg1a
:
861 case A_int_bad_extmsg1b
:
862 case A_int_bad_extmsg2a
:
863 case A_int_bad_extmsg2b
:
864 case A_int_bad_extmsg3a
:
865 case A_int_bad_extmsg3b
:
869 case A_int_cmd_bad_phase
:
870 case A_int_no_msgout1
:
871 case A_int_no_msgout2
:
872 case A_int_no_msgout3
:
873 case A_int_not_cmd_complete
:
874 case A_int_sel_no_ident
:
875 case A_int_sel_not_cmd
:
876 case A_int_status_not_msgin
:
877 case A_int_resel_not_msgin
:
881 sbcl
= NCR_read8(SBCL_REG
) & SBCL_PHASE_MASK
;
882 printk("scsi%d: Unimplemented script interrupt: %08x, phase %s\n",
883 host
->host_no
, dsps
, sbcl_to_phase(sbcl
));
885 /* resume_offset is zero, which will cause a host reset */
887 return resume_offset
;
891 /* A quick wrapper for sim710_intr_handle to grab the spin lock */
894 do_sim710_intr_handle(int irq
, void *dev_id
, struct pt_regs
*regs
)
898 spin_lock_irqsave(&io_request_lock
, flags
);
899 sim710_intr_handle(irq
, dev_id
, regs
);
900 spin_unlock_irqrestore(&io_request_lock
, flags
);
904 /* A "high" level interrupt handler */
907 sim710_intr_handle(int irq
, void *dev_id
, struct pt_regs
*regs
)
910 struct Scsi_Host
* host
= (struct Scsi_Host
*)dev_id
;
911 struct sim710_hostdata
*hostdata
= (struct sim710_hostdata
*)host
->hostdata
[0];
913 unsigned char istat
, dstat
;
914 unsigned char sstat0
;
915 u32 dsps
, resume_offset
= 0;
920 while ((istat
= NCR_read8(ISTAT_REG
)) & (ISTAT_SIP
|ISTAT_DIP
)) {
921 dsps
= NCR_read32(DSPS_REG
);
922 hostdata
->state
= STATE_HALTED
;
924 if (istat
& ISTAT_SIP
) {
925 sstat0
= NCR_read8(SSTAT0_REG
);
927 if (istat
& ISTAT_DIP
) {
928 udelay(10); /* Some comment somewhere about 10cycles
929 * between accesses to sstat0 and dstat ??? */
930 dstat
= NCR_read8(DSTAT_REG
);
932 DEB(DEB_INTS
, printk("scsi%d: Int %d, istat %02x, sstat0 %02x "
933 "dstat %02x, dsp [%04x], scratch %02x\n",
934 host
->host_no
, sim710_intrs
, istat
, sstat0
, dstat
,
935 (u32
*)(bus_to_virt(NCR_read32(DSP_REG
))) - hostdata
->script
,
936 NCR_read32(SCRATCH_REG
)));
937 if ((dstat
& DSTAT_SIR
) && dsps
== A_int_reselected
) {
938 /* Reselected. Identify the target from LCRC_REG, and
939 * update current command. If we were trying to select
940 * a device, then that command needs to go back on the
941 * issue_queue for later.
943 unsigned char lcrc
= NCR_read8(LCRC_REG_10
);
946 if (!(lcrc
& 0x7f)) {
947 printk("scsi%d: Reselected with LCRC = %02x\n",
948 host
->host_no
, lcrc
);
952 while (!(lcrc
& 1)) {
956 DEB(DEB_DISC
, printk("scsi%d: Reselected by ID %d\n",
958 if (hostdata
->running
) {
960 (void)NCR_read8(CTEST2_REG_700
);
962 DEB(DEB_DISC
, printk("scsi%d: Select of %d interrupted "
963 "by reselect from %d (%p)\n",
964 host
->host_no
, hostdata
->running
->target
,
965 id
, hostdata
->target
[id
].cur_cmd
));
966 cmd
= hostdata
->running
;
967 hostdata
->target
[cmd
->target
].cur_cmd
= NULL
;
968 cmd
->SCp
.ptr
= (unsigned char *) hostdata
->issue_queue
;
969 hostdata
->issue_queue
= cmd
;
971 cmd
= hostdata
->running
= hostdata
->target
[id
].cur_cmd
;
975 cmd
= hostdata
->running
;
978 printk("scsi%d: No active command!\n", host
->host_no
);
979 printk("scsi%d: Int %d, istat %02x, sstat0 %02x "
980 "dstat %02x, dsp [%04x], scratch %02x, dsps %08x\n",
981 host
->host_no
, sim710_intrs
, istat
, sstat0
, dstat
,
982 (u32
*)(bus_to_virt(NCR_read32(DSP_REG
))) - hostdata
->script
,
983 NCR_read32(SCRATCH_REG
), dsps
);
984 /* resume_offset is zero, which will cause a host reset */
986 else if (sstat0
& SSTAT0_700_STO
) {
987 DEB(DEB_TOUT
, printk("scsi%d: Selection timeout\n", host
->host_no
));
988 cmd
->result
= DID_NO_CONNECT
<< 16;
990 hostdata
->target
[cmd
->target
].cur_cmd
= NULL
;
991 resume_offset
= Ent_reselect
;
993 else if (dstat
& DSTAT_SIR
)
994 resume_offset
= handle_script_int(host
, cmd
);
995 else if (sstat0
& SSTAT0_MA
) {
996 resume_offset
= handle_phase_mismatch(host
, cmd
);
998 else if (sstat0
& (SSTAT0_MA
|SSTAT0_SGE
|SSTAT0_UDC
|SSTAT0_RST
|SSTAT0_PAR
)) {
999 printk("scsi%d: Serious error, sstat0 = %02x\n", host
->host_no
,
1002 /* resume_offset is zero, which will cause a host reset */
1004 else if (dstat
& (DSTAT_BF
|DSTAT_ABRT
|DSTAT_SSI
|DSTAT_WTD
)) {
1005 printk("scsi%d: Serious error, dstat = %02x\n", host
->host_no
,
1008 /* resume_offset is zero, which will cause a host reset */
1010 else if (dstat
& DSTAT_IID
) {
1011 /* This can be due to a quick reselect while doing a WAIT
1014 resume_offset
= handle_idd(host
, cmd
);
1018 printk("scsi%d: Spurious interrupt!\n", host
->host_no
);
1019 /* resume_offset is zero, which will cause a host reset */
1023 if (resume_offset
) {
1024 if (resume_offset
== Ent_reselect
) {
1025 hostdata
->running
= NULL
;
1026 hostdata
->state
= STATE_IDLE
;
1029 hostdata
->state
= STATE_BUSY
;
1030 DEB(DEB_RESUME
, printk("scsi%d: Resuming at script[0x%x]\n",
1031 host
->host_no
, resume_offset
/4));
1032 #ifdef DEBUG_LIMIT_INTS
1033 if (sim710_intrs
< DEBUG_LIMIT_INTS
)
1035 NCR_write32(DSP_REG
, virt_to_bus(hostdata
->script
+resume_offset
/4));
1036 if (resume_offset
== Ent_reselect
)
1037 run_process_issue_queue(hostdata
);
1040 printk("scsi%d: Failed to handle interrupt. Failing commands "
1041 "and resetting SCSI bus and chip\n", host
->host_no
);
1042 mdelay(4000); /* Give chance to read screen!! */
1046 restore_flags(flags
);
1051 run_command (struct sim710_hostdata
*hostdata
, Scsi_Cmnd
*cmd
)
1053 struct Scsi_Host
*host
= cmd
->host
;
1054 struct sim710_target
*targdata
= hostdata
->target
+ cmd
->target
;
1055 int i
, datain
, dataout
, sg_start
;
1056 u32
*dip
, *dop
, dsa
;
1058 DEB(DEB_CMND
, printk("scsi%d: id%d starting ", host
->host_no
,
1060 DEB(DEB_CMND
, print_command(cmd
->cmnd
));
1062 switch (cmd
->cmnd
[0]) {
1069 case READ_BLOCK_LIMITS
:
1080 case TEST_UNIT_READY
:
1081 case ALLOW_MEDIUM_REMOVAL
:
1083 datain
= dataout
= 0;
1086 datain
= dataout
= 1;
1089 memcpy(targdata
->dsa_cdb
, cmd
->cmnd
, MAX_CMND
);
1091 targdata
->dsa_msgout
[0] =
1092 IDENTIFY((opt_nodisc
& (1<<cmd
->target
)) ? 0 : 1 ,0);
1093 if (hostdata
->negotiate
& (1 << cmd
->target
)) {
1094 if (opt_noneg
& (1 << cmd
->target
)) {
1095 hostdata
->negotiate
^= (1 << cmd
->target
);
1096 targdata
->dsa
[DSA_MSGOUT
] = 1;
1099 DEB(DEB_SYNC
, printk("scsi%d: Negotiating async transfers "
1101 host
->host_no
, cmd
->target
));
1102 memcpy(targdata
->dsa_msgout
+1, async_message
, sizeof(async_message
));
1103 targdata
->dsa
[DSA_MSGOUT
] = sizeof(async_message
) + 1;
1107 targdata
->dsa
[DSA_MSGOUT
] = 1;
1109 targdata
->dsa_msgin
[0] = 0xff;
1110 targdata
->dsa_status
[0] = 0xff;
1112 targdata
->dsa
[DSA_SELECT
] = (1 << cmd
->target
) << 16;
1113 targdata
->dsa
[DSA_MSGOUT
+1] = virt_to_bus(targdata
->dsa_msgout
);
1114 targdata
->dsa
[DSA_CMND
] = cmd
->cmd_len
;
1115 targdata
->dsa
[DSA_CMND
+1] = virt_to_bus(targdata
->dsa_cdb
);
1116 targdata
->dsa
[DSA_STATUS
] = 1;
1117 targdata
->dsa
[DSA_STATUS
+1] = virt_to_bus(targdata
->dsa_status
);
1118 targdata
->dsa
[DSA_MSGIN
] = 1;
1119 targdata
->dsa
[DSA_MSGIN
+1] = virt_to_bus(targdata
->dsa_msgin
);
1121 sg_start
= (MAX_SG
- (cmd
->use_sg
? cmd
->use_sg
: 1)) * 2;
1122 dip
= targdata
->dsa
+ DSA_DATAIN
+ sg_start
;
1123 dop
= targdata
->dsa
+ DSA_DATAOUT
+ sg_start
;
1125 for (i
= 0; cmd
->use_sg
? (i
< cmd
->use_sg
) : !i
; i
++) {
1126 u32 vbuf
= cmd
->use_sg
?
1127 (u32
)(((struct scatterlist
*)cmd
->buffer
)[i
].address
) :
1128 (u32
)(cmd
->request_buffer
);
1129 u32 bbuf
= virt_to_bus((void *)vbuf
);
1130 u32 cnt
= cmd
->use_sg
?
1131 ((struct scatterlist
*)cmd
->buffer
)[i
].length
:
1132 cmd
->request_bufflen
;
1135 #ifdef CONFIG_TP34V_SCSI
1136 cache_clear(virt_to_phys((void *)vbuf
), cnt
);
1142 #ifdef CONFIG_TP34V_SCSI
1143 cache_push(virt_to_phys((void *)vbuf
), cnt
);
1149 targdata
->data_out_jump
= hostdata
->script
[Ent_patch_output_data
/4+1] =
1150 virt_to_bus(hostdata
->script
+ Ent_patch_output_data
/4 + sg_start
+ 2);
1151 targdata
->data_in_jump
= hostdata
->script
[Ent_patch_input_data
/4+1] =
1152 virt_to_bus(hostdata
->script
+ Ent_patch_input_data
/4 + sg_start
+ 2);
1154 for (i
= 0, dsa
= virt_to_bus(targdata
->dsa
); i
< 4; i
++) {
1155 u32 v
= hostdata
->script
[Ent_patch_new_dsa
/4 + i
* 2];
1158 v
|= (dsa
& 0xff) << 8;
1159 hostdata
->script
[Ent_patch_new_dsa
/4 + i
* 2] = v
;
1162 hostdata
->running
= targdata
->cur_cmd
= cmd
;
1163 hostdata
->state
= STATE_BUSY
;
1165 NCR_write8(ISTAT_REG
, ISTAT_10_SIGP
);
1169 static volatile int process_issue_queue_running
= 0;
1171 static __inline__
void
1172 run_process_issue_queue(struct sim710_hostdata
*hostdata
)
1174 unsigned long flags
;
1177 if (!process_issue_queue_running
) {
1178 process_issue_queue_running
= 1;
1179 process_issue_queue(hostdata
, flags
);
1181 * process_issue_queue_running is cleared in process_issue_queue
1182 * once it can't do more work, and process_issue_queue exits with
1183 * interrupts disabled.
1186 restore_flags (flags
);
1191 * Function : process_issue_queue (hostdata, flags)
1193 * Purpose : Start next command for any idle target.
1195 * NOTE : process_issue_queue exits with interrupts *disabled*, so the
1196 * caller must reenable them if it desires.
1198 * NOTE : process_issue_queue should be called from both
1199 * sim710_queue_command() and from the interrupt handler
1200 * after command completion.
1204 process_issue_queue (struct sim710_hostdata
*hostdata
, unsigned long flags
)
1206 Scsi_Cmnd
*tmp
, *prev
;
1210 * We run (with interrupts disabled) until we're sure that none of
1211 * the host adapters have anything that can be done, at which point
1212 * we set process_issue_queue_running to 0 and exit.
1214 * Interrupts are enabled before doing various other internal
1215 * instructions, after we've decided that we need to run through
1221 cli(); /* Freeze request queues */
1223 if (hostdata
->issue_queue
) {
1224 if (hostdata
->state
== STATE_DISABLED
) {
1225 tmp
= (Scsi_Cmnd
*) hostdata
->issue_queue
;
1226 hostdata
->issue_queue
= (Scsi_Cmnd
*) tmp
->SCp
.ptr
;
1227 tmp
->result
= (DID_BAD_TARGET
<< 16);
1228 tmp
->scsi_done (tmp
);
1231 else if (hostdata
->state
== STATE_IDLE
) {
1232 for (tmp
= hostdata
->issue_queue
, prev
= NULL
; tmp
;
1233 prev
= tmp
, tmp
= (Scsi_Cmnd
*) tmp
->SCp
.ptr
) {
1234 if (hostdata
->target
[tmp
->target
].cur_cmd
== NULL
) {
1236 prev
->SCp
.ptr
= tmp
->SCp
.ptr
;
1238 hostdata
->issue_queue
= (Scsi_Cmnd
*) tmp
->SCp
.ptr
;
1239 tmp
->SCp
.ptr
= NULL
;
1240 run_command (hostdata
, tmp
);
1242 } /* if target/lun is not busy */
1243 } /* scan issue queue for work */
1244 } /* host is idle */
1245 } /* if hostdata->issue_queue */
1247 restore_flags (flags
);
1249 process_issue_queue_running
= 0;
1254 sim710_queuecommand(Scsi_Cmnd
* cmd
, void (*done
)(Scsi_Cmnd
*))
1256 struct Scsi_Host
*host
= cmd
->host
;
1257 struct sim710_hostdata
*hostdata
= (struct sim710_hostdata
*)host
->hostdata
[0];
1259 unsigned long flags
;
1262 /* Silently ignore luns other than zero! */
1263 cmd
->result
= (DID_BAD_TARGET
<< 16);
1268 DEB(DEB_CMND
, printk("scsi%d: id%d queuing ", host
->host_no
,
1270 DEB(DEB_CMND
, print_command(cmd
->cmnd
));
1272 cmd
->scsi_done
= done
;
1273 cmd
->host_scribble
= NULL
;
1274 cmd
->SCp
.ptr
= NULL
;
1275 cmd
->SCp
.buffer
= NULL
;
1280 if (ignore_ids
& (1 << cmd
->target
)) {
1281 printk("scsi%d: ignoring target %d\n", host
->host_no
, cmd
->target
);
1282 cmd
->result
= (DID_BAD_TARGET
<< 16);
1284 restore_flags (flags
);
1287 #ifdef DEBUG_LIMIT_INTS
1288 if (sim710_intrs
> DEBUG_LIMIT_INTS
) {
1289 cmd
->result
= (DID_BAD_TARGET
<< 16);
1291 restore_flags (flags
);
1295 if (cmd
->use_sg
> MAX_SG
)
1296 panic ("cmd->use_sg = %d\n", cmd
->use_sg
);
1298 if (!(hostdata
->issue_queue
) || (cmd
->cmnd
[0] == REQUEST_SENSE
)) {
1299 cmd
->SCp
.ptr
= (unsigned char *) hostdata
->issue_queue
;
1300 hostdata
->issue_queue
= cmd
;
1302 for (tmp
= hostdata
->issue_queue
; tmp
->SCp
.ptr
;
1303 tmp
= (Scsi_Cmnd
*) tmp
->SCp
.ptr
);
1304 tmp
->SCp
.ptr
= (unsigned char *) cmd
;
1306 restore_flags (flags
);
1307 run_process_issue_queue(hostdata
);
1313 sim710_detect(Scsi_Host_Template
* tpnt
)
1315 unsigned char irq_vector
;
1316 unsigned char scsi_id
;
1317 unsigned int base_addr
;
1318 struct Scsi_Host
* host
= NULL
;
1319 struct sim710_hostdata
*hostdata
;
1327 sim710_setup(sim710
, (int *)0);
1330 if (no_of_boards
< 0) {
1331 printk("sim710: NCR53C710 driver disabled\n");
1336 /* If board details have been specified via boot/module parameters,
1337 * then don't bother probing.
1339 if (no_of_boards
== 0) {
1342 int mca_53c710_ids
[] = MCA_53C710_IDS
;
1343 int *id_to_check
= mca_53c710_ids
;
1344 static int io_004f_by_pos
[] = MCA_004F_IO_PORTS
;
1345 static int irq_004f_by_pos
[] = MCA_004F_IRQS
;
1346 static int io_01bb_by_pos
[] = MCA_01BB_IO_PORTS
;
1347 static int irq_01bb_by_pos
[] = MCA_01BB_IRQS
;
1349 while ( *id_to_check
&& no_of_boards
< MAXBOARDS
) {
1353 if ((slot
= mca_find_adapter(*id_to_check
, 0)) != MCA_NOTFOUND
) {
1355 pos
[0] = mca_read_stored_pos(slot
, 2);
1356 pos
[1] = mca_read_stored_pos(slot
, 3);
1357 pos
[2] = mca_read_stored_pos(slot
, 4);
1360 * 01BB & 01BA port base by bits 7,6,5,4,3,2 in pos[2]
1362 * 000000 <disabled> 001010 0x2800
1363 * 000001 <invalid> 001011 0x2C00
1364 * 000010 0x0800 001100 0x3000
1365 * 000011 0x0C00 001101 0x3400
1366 * 000100 0x1000 001110 0x3800
1367 * 000101 0x1400 001111 0x3C00
1368 * 000110 0x1800 010000 0x4000
1369 * 000111 0x1C00 010001 0x4400
1370 * 001000 0x2000 010010 0x4800
1371 * 001001 0x2400 010011 0x4C00
1374 * 00F4 port base by bits 3,2,1 in pos[0]
1376 * 000 <disabled> 001 0x200
1377 * 010 0x300 011 0x400
1378 * 100 0x500 101 0x600
1380 * 01BB & 01BA IRQ is specified in pos[0] bits 7 and 6:
1385 * 00F4 IRQ specified by bits 6,5,4 in pos[0]
1391 if ( *id_to_check
== 0x01bb || *id_to_check
== 0x01ba ) {
1392 bases
[no_of_boards
] = io_01bb_by_pos
[(pos
[2] & 0xFC) >> 2];
1393 irq_vectors
[no_of_boards
] =
1394 irq_01bb_by_pos
[((pos
[0] & 0xC0) >> 6)];
1395 if (bases
[no_of_boards
] == 0x0000)
1396 printk("sim710: NCR53C710 Adapter ID 0x01bb is disabled.\n");
1399 if ( *id_to_check
== 0x01bb )
1400 mca_set_adapter_name( slot
,
1401 "NCR 3360/3430 SCSI SubSystem" );
1403 mca_set_adapter_name(slot
,
1404 "NCR Dual SIOP SCSI Host Adapter Board");
1407 else if ( *id_to_check
== 0x004f ) {
1408 bases
[no_of_boards
] = io_004f_by_pos
[((pos
[0] & 0x0E) >> 1)];
1409 irq_vectors
[no_of_boards
] =
1410 irq_004f_by_pos
[((pos
[0] & 0x70) >> 4) - 4];
1411 if (bases
[no_of_boards
] == 0x0000)
1412 printk("sim710: NCR53C710 Adapter ID 0x004f is disabled.\n");
1415 mca_set_adapter_name(slot
,
1416 "NCR 53c710 SCSI Host Adapter Board");
1425 if (!no_of_boards
) {
1426 printk("sim710: No NCR53C710 adapter found.\n");
1430 size
= sizeof(struct sim710_hostdata
);
1432 while (size
> (PAGE_SIZE
<< order
))
1434 size
= PAGE_SIZE
<< order
;
1436 DEB(DEB_ANY
, printk("sim710: hostdata %d bytes, size %d, order %d\n",
1437 sizeof(struct sim710_hostdata
), size
, order
));
1439 tpnt
->proc_name
= "sim710";
1441 for(indx
= 0; indx
< no_of_boards
; indx
++) {
1442 host
= scsi_register(tpnt
, 4);
1443 host
->hostdata
[0] = __get_free_pages(GFP_ATOMIC
, order
);
1444 if (host
->hostdata
[0] == 0)
1445 panic ("sim710: Couldn't get hostdata memory");
1446 hostdata
= (struct sim710_hostdata
*)host
->hostdata
[0];
1447 memset(hostdata
, 0, size
);
1448 #ifdef CONFIG_TP34V_SCSI
1449 cache_push(virt_to_phys(hostdata
), size
);
1450 cache_clear(virt_to_phys(hostdata
), size
);
1451 kernel_set_cachemode((void *)hostdata
,size
,IOMAP_NOCACHE_SER
);
1454 base_addr
= bases
[indx
];
1455 irq_vector
= irq_vectors
[indx
];
1456 printk("sim710: Configuring Sim710 (SCSI-ID %d) at %x, IRQ %d\n",
1457 scsi_id
, base_addr
, irq_vector
);
1458 DEB(DEB_ANY
, printk("sim710: hostdata = %p (%d bytes), dsa0 = %p\n",
1459 hostdata
, sizeof(struct sim710_hostdata
),
1460 hostdata
->target
[0].dsa
));
1461 hostdata
->chip
= indx
;
1462 host
->irq
= irq_vector
;
1463 host
->this_id
= scsi_id
;
1464 host
->unique_id
= base_addr
;
1465 host
->base
= (char *)base_addr
;
1469 revision
= (NCR_read8(CTEST8_REG
) & 0xF0) >> 4;
1470 printk("scsi%d: Revision 0x%x\n",host
->host_no
,revision
);
1472 sim710_soft_reset(host
);
1474 sim710_driver_init(host
);
1476 #ifdef CONFIG_TP34V_SCSI
1477 if (request_irq(irq_vector
,do_sim710_intr_handle
, 0, "sim710", host
))
1479 if (request_irq(irq_vector
,do_sim710_intr_handle
, SA_INTERRUPT
, "sim710", host
))
1482 printk("scsi%d : IRQ%d not free, detaching\n",
1483 host
->host_no
, host
->irq
);
1485 scsi_unregister (host
);
1489 request_region((u32
)host
->base
, 64, "sim710");
1493 NCR_write32(DSP_REG
, virt_to_bus(hostdata
->script
+Ent_reselect
/4));
1494 hostdata
->state
= STATE_IDLE
;
1500 sim710_abort(Scsi_Cmnd
* cmd
)
1502 struct Scsi_Host
* host
= cmd
->host
;
1504 printk("scsi%d: Unable to abort command for target %d\n",
1505 host
->host_no
, cmd
->target
);
1510 * This is a device reset. Need to select and send a Bus Device Reset msg.
1514 sim710_dev_reset(Scsi_Cmnd
* SCpnt
)
1516 struct Scsi_Host
* host
= SCpnt
->host
;
1518 printk("scsi%d: Unable to send Bus Device Reset for target %d\n",
1519 host
->host_no
, SCpnt
->target
);
1524 * This is bus reset. We need to reset the bus and fail any active commands.
1528 sim710_bus_reset(Scsi_Cmnd
* SCpnt
)
1530 struct Scsi_Host
* host
= SCpnt
->host
;
1532 printk("scsi%d: Unable to do SCSI bus reset\n", host
->host_no
);
1537 full_reset(struct Scsi_Host
* host
)
1539 struct sim710_hostdata
*hostdata
= (struct sim710_hostdata
*)
1545 printk("scsi%d: dsp = %08x (script[0x%04x]), scratch = %08x\n",
1546 host
->host_no
, NCR_read32(DSP_REG
),
1547 ((u32
)bus_to_virt(NCR_read32(DSP_REG
)) - (u32
)hostdata
->script
)/4,
1548 NCR_read32(SCRATCH_REG
));
1550 for (target
= 0; target
< 7; target
++) {
1551 if ((cmd
= hostdata
->target
[target
].cur_cmd
)) {
1552 printk("scsi%d: Failing command for ID%d\n",
1553 host
->host_no
, target
);
1554 cmd
->result
= DID_RESET
<< 16;
1555 cmd
->scsi_done(cmd
);
1556 hostdata
->target
[target
].cur_cmd
= NULL
;
1560 sim710_soft_reset(host
);
1561 sim710_driver_init(host
);
1563 NCR_write32(DSP_REG
, virt_to_bus(hostdata
->script
+Ent_reselect
/4));
1564 hostdata
->state
= STATE_IDLE
;
1566 run_process_issue_queue(hostdata
);
1572 * This is host reset. We need to reset the chip and the bus.
1576 sim710_host_reset(Scsi_Cmnd
* SCpnt
)
1578 struct Scsi_Host
* host
= SCpnt
->host
;
1580 printk("scsi%d: >>>>>>>>>>>> Host reset <<<<<<<<<<<<\n", host
->host_no
);
1582 return full_reset(host
);
1588 sim710_release(struct Scsi_Host
*host
)
1590 free_irq(host
->irq
, host
);
1592 release_region((u32
)host
->base
, 64);
1597 Scsi_Host_Template driver_template
= SIM710_SCSI
;
1599 #include "scsi_module.c"