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 #include <linux/config.h>
62 #include <linux/module.h>
64 #include <linux/version.h>
65 #include <linux/kernel.h>
66 #include <linux/types.h>
67 #include <linux/string.h>
68 #include <linux/ioport.h>
69 #include <linux/delay.h>
70 #include <linux/sched.h>
71 #include <linux/proc_fs.h>
72 #include <linux/init.h>
73 #include <linux/mca.h>
75 #include <asm/system.h>
76 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,17)
77 #include <linux/spinlock.h>
78 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,93)
79 #include <asm/spinlock.h>
82 #include <asm/pgtable.h>
83 #include <asm/byteorder.h>
84 #include <linux/blk.h>
86 #ifdef CONFIG_TP34V_SCSI
88 #include <asm/tp34vhw.h>
91 #elif defined(CONFIG_MCA)
96 * For each known microchannel card using the 53c710 we need a list
97 * of possible IRQ and IO settings, as well as their corresponding
98 * bit assignment in pos[]. This might get cumbersome if there
99 * are more than a few cards (I only know of 2 at this point).
102 #define MCA_53C710_IDS { 0x01bb, 0x01ba, 0x004f }
104 /* CARD ID 01BB and 01BA use the same pos values */
106 #define MCA_01BB_IO_PORTS { 0x0000, 0x0000, 0x0800, 0x0C00, 0x1000, 0x1400, \
107 0x1800, 0x1C00, 0x2000, 0x2400, 0x2800, \
108 0x2C00, 0x3000, 0x3400, 0x3800, 0x3C00, \
109 0x4000, 0x4400, 0x4800, 0x4C00, 0x5000 }
111 #define MCA_01BB_IRQS { 3, 5, 11, 14 }
115 #define MCA_004F_IO_PORTS { 0x0000, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600 }
117 #define MCA_004F_IRQS { 5, 9, 14 }
121 /* Assume an Intel platform */
131 #include<linux/stat.h>
134 #undef DEBUG_LIMIT_INTS /* Define to 10 to hang driver after 10 ints */
136 /* Debug options available via the "debug:0x1234" parameter */
138 #define DEB_NONE 0x0000 /* Nothing */
139 #define DEB_HALT 0x0001 /* Detailed trace of chip halt funtion */
140 #define DEB_REGS 0x0002 /* All chip register read/writes */
141 #define DEB_SYNC 0x0004 /* Sync/async negotiation */
142 #define DEB_PMM 0x0008 /* Phase mis-match handling */
143 #define DEB_INTS 0x0010 /* General interrupt trace */
144 #define DEB_TOUT 0x0020 /* Selection timeouts */
145 #define DEB_RESUME 0x0040 /* Resume addresses for the script */
146 #define DEB_CMND 0x0080 /* Commands and status returned */
147 #define DEB_FIXUP 0x0100 /* Fixup of scsi addresses */
148 #define DEB_DISC 0x0200 /* Disconnect/reselect handling */
150 #define DEB_ANY 0xffff /* Any and all debug options */
153 #define DEB(m,x) if (sim710_debug & m) x
154 int sim710_debug
= 0;
159 /* Redefine scsi_done to force renegotiation of (a)sync transfers
160 * following any failed command.
163 #define SCSI_DONE(cmd) { \
164 DEB(DEB_CMND, printk("scsi%d: Complete %08x\n", \
165 host->host_no, cmd->result)); \
167 hostdata->negotiate |= (1 << cmd->target); \
168 cmd->scsi_done(cmd); \
172 #define offsetof(t, m) ((size_t) (&((t *)0)->m))
175 #define STATE_INITIALISED 0
176 #define STATE_HALTED 1
179 #define STATE_DISABLED 4
181 #define MAXBOARDS 2 /* Increase this and the sizes of the
182 arrays below, if you need more.. */
186 char *sim710
; /* command line passed by insmod */
188 MODULE_AUTHOR("Richard Hirst");
189 MODULE_DESCRIPTION("Simple NCR53C710 driver");
190 MODULE_PARM(sim710
, "s");
194 static int sim710_errors
= 0; /* Count of error interrupts */
195 static int sim710_intrs
= 0; /* Count of all interrupts */
196 static int ignore_ids
= 0; /* Accept all SCSI IDs */
197 static int opt_nodisc
= 0; /* Allow disconnect on all IDs */
198 static int opt_noneg
= 0; /* Allow SDTR negotiation on all IDs */
200 #ifdef CONFIG_TP34V_SCSI
202 /* Special hardwired case for Tadpole TP34V at the moment, otherwise
203 * boot parameters 'sim710=addr:0x8000,irq:15' (for example) must be given.
206 static int no_of_boards
= 2;
208 static unsigned int bases
[MAXBOARDS
] = {
209 TP34V_SCSI0_BASE
, TP34V_SCSI1_BASE
211 static unsigned int irq_vectors
[MAXBOARDS
] = {
212 TP34V_SCSI0_VECTOR
, TP34V_SCSI1_VECTOR
214 static unsigned int irq_index
[MAXBOARDS
] = {
215 TP34V_SCSI0_IRQ_INDEX
, TP34V_SCSI1_IRQ_INDEX
220 /* All other cases use boot/module params, or auto-detect */
222 static int no_of_boards
= 0;
224 static unsigned int bases
[MAXBOARDS
] = {
227 static unsigned int irq_vectors
[MAXBOARDS
] = {
233 /* The SCSI Script!!! */
235 #include "sim710_d.h"
237 /* Now define offsets in the DSA, as (A_dsa_xxx/4) */
239 #define DSA_SELECT (A_dsa_select/4)
240 #define DSA_MSGOUT (A_dsa_msgout/4)
241 #define DSA_CMND (A_dsa_cmnd/4)
242 #define DSA_STATUS (A_dsa_status/4)
243 #define DSA_MSGIN (A_dsa_msgin/4)
244 #define DSA_DATAIN (A_dsa_datain/4)
245 #define DSA_DATAOUT (A_dsa_dataout/4)
246 #define DSA_SIZE (A_dsa_size/4)
248 #define MAX_SG 128 /* Scatter/Gather elements */
256 struct sim710_hostdata
{
258 Scsi_Cmnd
* issue_queue
;
262 u8 reselected_identify
;
263 u8 msgin_buf
[MAX_MSGIN
];
265 struct sim710_target
{
270 u32 dsa
[DSA_SIZE
]; /* SCSI Script DSA area */
271 u8 dsa_msgout
[MAX_MSGOUT
];
272 u8 dsa_msgin
[MAX_MSGIN
];
273 u8 dsa_cdb
[MAX_CMND
];
274 u8 dsa_status
[MAX_STATUS
];
277 u32 script
[sizeof(SCRIPT
)/4] __attribute__ ((aligned (4)));
281 /* Template to request asynchronous transfers */
283 static const unsigned char async_message
[] = {
284 EXTENDED_MESSAGE
, 3 /* length */, EXTENDED_SDTR
, 0, 0 /* asynchronous */};
287 static void sim710_intr_handle(int irq
, void *dev_id
, struct pt_regs
*regs
);
288 static void do_sim710_intr_handle(int irq
, void *dev_id
, struct pt_regs
*regs
);
289 static __inline__
void run_process_issue_queue(struct sim710_hostdata
*);
290 static void process_issue_queue (struct sim710_hostdata
*, unsigned long flags
);
291 static int full_reset(struct Scsi_Host
* host
);
295 * Function: int param_setup(char *str)
305 param_setup(char *str
)
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: unexpected boot option '%.*s' ignored\n", (int)(pc
-cur
+1), cur
);
353 if ((cur
= strchr(cur
, ARG_SEP
)) != NULL
)
359 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,13)
361 __setup("sim710=", param_setup
);
364 /* Old boot param syntax support */
366 sim710_setup(char *str
, int *ints
)
374 * Function: static const char *sbcl_to_phase (int sbcl)
378 sbcl_to_phase (int sbcl
) {
379 switch (sbcl
& SBCL_PHASE_MASK
) {
380 case SBCL_PHASE_DATAIN
:
382 case SBCL_PHASE_DATAOUT
:
384 case SBCL_PHASE_MSGIN
:
386 case SBCL_PHASE_MSGOUT
:
388 case SBCL_PHASE_CMDOUT
:
390 case SBCL_PHASE_STATIN
:
399 * Function: static void disable (struct Scsi_Host *host)
403 disable (struct Scsi_Host
*host
)
405 struct sim710_hostdata
*hostdata
= (struct sim710_hostdata
*)
408 hostdata
->state
= STATE_DISABLED
;
409 printk (KERN_ALERT
"scsi%d : disabled. Unload and reload\n",
415 * Function : static int ncr_halt (struct Scsi_Host *host)
417 * Purpose : halts the SCSI SCRIPTS(tm) processor on the NCR chip
419 * Inputs : host - SCSI chip to halt
421 * Returns : 0 on success
425 ncr_halt (struct Scsi_Host
*host
)
428 unsigned char istat
, tmp
;
429 struct sim710_hostdata
*hostdata
= (struct sim710_hostdata
*)
435 /* Stage 0 : eat all interrupts
437 Stage 2 : eat all but abort interrupts
438 Stage 3 : eat all interrupts
442 DEB(DEB_HALT
, printk("ncr_halt: writing ISTAT_ABRT\n"));
443 NCR_write8(ISTAT_REG
, ISTAT_ABRT
);
446 istat
= NCR_read8 (ISTAT_REG
);
447 if (istat
& ISTAT_SIP
) {
448 DEB(DEB_HALT
, printk("ncr_halt: got ISTAT_SIP, istat=%02x\n", istat
));
449 tmp
= NCR_read8(SSTAT0_REG
);
450 DEB(DEB_HALT
, printk("ncr_halt: got SSTAT0_REG=%02x\n", tmp
));
451 } else if (istat
& ISTAT_DIP
) {
452 DEB(DEB_HALT
, printk("ncr_halt: got ISTAT_DIP, istat=%02x\n", istat
));
453 tmp
= NCR_read8(DSTAT_REG
);
454 DEB(DEB_HALT
, printk("ncr_halt: got DSTAT_REG=%02x\n", tmp
));
456 if (tmp
& DSTAT_ABRT
) {
457 DEB(DEB_HALT
, printk("ncr_halt: got DSTAT_ABRT, clearing istat\n"));
458 NCR_write8(ISTAT_REG
, 0);
461 printk(KERN_ALERT
"scsi%d : could not halt NCR chip\n",
467 if (!(istat
& (ISTAT_SIP
|ISTAT_DIP
))) {
474 hostdata
->state
= STATE_HALTED
;
475 restore_flags(flags
);
480 * Function : static void sim710_soft_reset (struct Scsi_Host *host)
482 * Purpose : perform a soft reset of the NCR53c7xx chip
484 * Inputs : host - pointer to this host adapter's structure
486 * Preconditions : sim710_init must have been called for this
492 sim710_soft_reset (struct Scsi_Host
*host
)
495 #ifdef CONFIG_TP34V_SCSI
496 struct sim710_hostdata
*hostdata
= (struct sim710_hostdata
*)
502 #ifdef CONFIG_TP34V_SCSI
503 tpvic
.loc_icr
[irq_index
[hostdata
->chip
]].icr
= 0x80;
506 * Do a soft reset of the chip so that everything is
507 * reinitialized to the power-on state.
509 * Basically follow the procedure outlined in the NCR53c700
510 * data manual under Chapter Six, How to Use, Steps Necessary to
511 * Start SCRIPTS, with the exception of actually starting the
512 * script and setting up the synchronous transfer gunk.
515 /* XXX Should we reset the scsi bus here? */
517 NCR_write8(SCNTL1_REG
, SCNTL1_RST
); /* Reset the bus */
519 NCR_write8(SCNTL1_REG
, 0);
523 NCR_write8(ISTAT_REG
, ISTAT_10_SRST
); /* Reset the chip */
525 NCR_write8(ISTAT_REG
, 0);
527 mdelay(1000); /* Let devices recover */
529 NCR_write8(DCNTL_REG
, DCNTL_10_COM
| DCNTL_700_CF_3
);
530 NCR_write8(CTEST7_REG
, CTEST7_10_CDIS
|CTEST7_STD
);
531 NCR_write8(DMODE_REG
, DMODE_10_BL_8
| DMODE_10_FC2
);
532 NCR_write8(SCID_REG
, 1 << host
->this_id
);
533 NCR_write8(SBCL_REG
, 0);
534 NCR_write8(SXFER_REG
, 0);
535 NCR_write8(SCNTL1_REG
, SCNTL1_ESR_700
);
536 NCR_write8(SCNTL0_REG
, SCNTL0_EPC
| SCNTL0_EPG_700
| SCNTL0_ARB1
|
539 NCR_write8(DIEN_REG
, DIEN_700_BF
|
540 DIEN_ABRT
| DIEN_SSI
| DIEN_SIR
| DIEN_700_OPC
);
542 NCR_write8(SIEN_REG_700
,
543 SIEN_PAR
| SIEN_700_STO
| SIEN_RST
| SIEN_UDC
| SIEN_SGE
| SIEN_MA
);
546 #ifdef CONFIG_TP34V_SCSI
547 tpvic
.loc_icr
[irq_index
[hostdata
->chip
]].icr
= 0x30 | TP34V_SCSI0n1_IPL
;
550 restore_flags(flags
);
555 * Function : static void sim710_driver_init (struct Scsi_Host *host)
557 * Purpose : Initialize internal structures, as required on startup, or
558 * after a SCSI bus reset.
560 * Inputs : host - pointer to this host adapter's structure
564 sim710_driver_init (struct Scsi_Host
*host
)
566 struct sim710_hostdata
*hostdata
= (struct sim710_hostdata
*)
570 hostdata
->running
= NULL
;
571 memcpy (hostdata
->script
, SCRIPT
, sizeof(SCRIPT
));
572 for (i
= 0; i
< PATCHES
; i
++)
573 hostdata
->script
[LABELPATCHES
[i
]] += virt_to_bus(hostdata
->script
);
574 patch_abs_32 (hostdata
->script
, 0, reselected_identify
,
575 virt_to_bus((void *)&(hostdata
->reselected_identify
)));
576 patch_abs_32 (hostdata
->script
, 0, msgin_buf
,
577 virt_to_bus((void *)&(hostdata
->msgin_buf
[0])));
578 hostdata
->state
= STATE_INITIALISED
;
579 hostdata
->negotiate
= 0xff;
583 /* Handle incoming Synchronous data transfer request. If our negotiate
584 * flag is set then this is a response to our request, otherwise it is
585 * spurious request from the target. Don't really expect target initiated
586 * SDTRs, because we always negotiate on the first command. Could still
588 * The chip is currently paused with ACK asserted o the last byte of the
590 * resa is the resume address if the message is in response to our outgoing
591 * SDTR. Only possible on initial identify.
592 * resb is the resume address if the message exchange is initiated by the
597 handle_sdtr (struct Scsi_Host
* host
, Scsi_Cmnd
* cmd
, u32 resa
, u32 resb
)
599 struct sim710_hostdata
*hostdata
= (struct sim710_hostdata
*)host
->hostdata
[0];
600 struct sim710_target
*targdata
= hostdata
->target
+ cmd
->target
;
603 if (resa
&& hostdata
->negotiate
& (1 << cmd
->target
)) {
604 DEB(DEB_SYNC
, printk("scsi%d: Response to host SDTR = %02x %02x\n",
605 host
->host_no
, hostdata
->msgin_buf
[3], hostdata
->msgin_buf
[4]));
606 /* We always issue an SDTR with the identify, so we must issue
609 resume_offset
= resa
;
610 hostdata
->negotiate
&= ~(1 << cmd
->target
);
613 DEB(DEB_SYNC
, printk("scsi%d: Target initiated SDTR = %02x %02x\n",
614 host
->host_no
, hostdata
->msgin_buf
[3], hostdata
->msgin_buf
[4]));
615 memcpy(targdata
->dsa_msgout
, async_message
, sizeof(async_message
));
616 targdata
->dsa
[DSA_MSGOUT
] = sizeof(async_message
);
617 /* I guess the target could do this anytime; we have to send our
618 * response, and then continue (sending the CDB if not already done).
620 resume_offset
= resb
;
622 return resume_offset
;
627 * Function : static int datapath_residual (Scsi_Host *host)
629 * Purpose : return residual data count of what's in the chip.
631 * Inputs : host - SCSI host
635 datapath_residual (struct Scsi_Host
*host
) {
636 int count
, synchronous
, sstat
;
639 count
= ((NCR_read8 (DFIFO_REG
) & DFIFO_10_BO_MASK
) -
640 (NCR_read32 (DBC_REG
) & DFIFO_10_BO_MASK
)) & DFIFO_10_BO_MASK
;
641 synchronous
= NCR_read8 (SXFER_REG
) & SXFER_MO_MASK
;
642 ddir
= NCR_read8 (CTEST0_REG_700
) & CTEST0_700_DDIR
;
647 count
+= (NCR_read8 (SSTAT2_REG
) & SSTAT2_FF_MASK
) >> SSTAT2_FF_SHIFT
;
649 if (NCR_read8 (SSTAT1_REG
) & SSTAT1_ILF
)
653 sstat
= NCR_read8 (SSTAT1_REG
);
654 if (sstat
& SSTAT1_OLF
)
656 if (synchronous
&& (sstat
& SSTAT1_ORF
))
664 handle_idd (struct Scsi_Host
* host
, Scsi_Cmnd
* cmd
)
666 struct sim710_hostdata
*hostdata
=
667 (struct sim710_hostdata
*)host
->hostdata
[0];
668 struct sim710_target
*targdata
= hostdata
->target
+ cmd
->target
;
669 u32 resume_offset
= 0, index
;
671 index
= (u32
)((u32
*)(bus_to_virt(NCR_read32(DSP_REG
))) - hostdata
->script
);
674 case Ent_wait_disc_complete
/4 + 2:
675 cmd
->result
= targdata
->dsa_status
[0];
677 targdata
->cur_cmd
= NULL
;
678 resume_offset
= Ent_reselect
;
680 case Ent_wait_disc2
/4 + 2:
681 /* Disconnect after command - just wait for a reselect */
682 targdata
->resume_offset
= Ent_resume_msgin2a
;
683 resume_offset
= Ent_reselect
;
685 case Ent_wait_disc3
/4 + 2:
686 /* Disconnect after the data phase */
687 targdata
->resume_offset
= Ent_resume_msgin3a
;
688 resume_offset
= Ent_reselect
;
690 case Ent_wait_disc1
/4 + 2:
691 /* Disconnect before command - not expected */
692 targdata
->resume_offset
= Ent_resume_msgin1a
;
693 resume_offset
= Ent_reselect
;
696 printk("scsi%d: Unexpected Illegal Instruction, script[%04x]\n",
697 host
->host_no
, index
);
699 /* resume_offset is zero, which will cause host reset */
701 return resume_offset
;
705 /* Handle a phase mismatch.
709 handle_phase_mismatch (struct Scsi_Host
* host
, Scsi_Cmnd
* cmd
)
711 struct sim710_hostdata
*hostdata
=
712 (struct sim710_hostdata
*)host
->hostdata
[0];
713 struct sim710_target
*targdata
= hostdata
->target
+ cmd
->target
;
714 u32 resume_offset
= 0, index
;
717 sbcl
= NCR_read8(SBCL_REG
) & SBCL_PHASE_MASK
;
718 index
= (u32
)((u32
*)(bus_to_virt(NCR_read32(DSP_REG
))) - hostdata
->script
);
720 DEB(DEB_PMM
, printk("scsi%d: Phase mismatch, phase %s (%x) at script[0x%x]\n",
721 host
->host_no
, sbcl_to_phase(sbcl
), sbcl
, index
));
722 DEB(DEB_PMM
, print_command(cmd
->cmnd
));
724 if (index
== Ent_done_ident
/4) {
725 /* Sending initial message out - probably rejecting our sync
726 * negotiation request.
728 NCR_write8(SOCL_REG
, 0); /* Negate ATN */
729 if (sbcl
== SBCL_PHASE_MSGIN
)
730 resume_offset
= Ent_resume_rej_ident
;
731 else if (sbcl
== SBCL_PHASE_CMDOUT
) {
732 /* Some old devices (SQ555) switch to cmdout after the first
733 * byte of an identify message, regardless of whether we
734 * have more bytes to send!
736 printk("scsi%d: Unexpected switch to CMDOUT during IDENTIFY\n",
738 resume_offset
= Ent_resume_cmd
;
741 printk("scsi%d: Unexpected phase change to %s on initial msgout\n",
742 host
->host_no
, sbcl_to_phase(sbcl
));
743 /* resume_offset is zero, which will cause a host reset */
745 hostdata
->negotiate
&= ~(1 << cmd
->target
);
747 else if (index
> Ent_patch_input_data
/4 &&
748 index
< Ent_patch_output_data
/4) {
749 /* DataIn transfer phase */
750 u32 sg_id
, oaddr
, olen
, naddr
, nlen
;
753 sg_id
= (index
- Ent_patch_input_data
/4 - 4) / 2;
754 targdata
->data_in_jump
= hostdata
->script
[Ent_patch_input_data
/4+1] =
755 virt_to_bus(hostdata
->script
+ Ent_patch_input_data
/4 + sg_id
* 2 + 2);
756 olen
= targdata
->dsa
[DSA_DATAIN
+ sg_id
* 2];
757 oaddr
= targdata
->dsa
[DSA_DATAIN
+ sg_id
* 2 + 1];
758 residual
= datapath_residual (host
);
760 printk("scsi%d: Residual count %d on DataIn - NOT expected!!!",
761 host
->host_no
, residual
);
762 naddr
= NCR_read32(DNAD_REG
) - residual
;
763 nlen
= (NCR_read32(DBC_REG
) & 0x00ffffff) + residual
;
764 DEB(DEB_PMM
, printk("scsi%d: DIN sg %d, old %08x/%08x, new %08x/%08x (%d)\n",
765 host
->host_no
, sg_id
, oaddr
, olen
, naddr
, nlen
, residual
));
766 if (oaddr
+olen
!= naddr
+nlen
) {
767 printk("scsi%d: PMM DIN counts error: 0x%x + 0x%x != 0x%x + 0x%x",
768 host
->host_no
, oaddr
, olen
, naddr
, nlen
);
771 targdata
->dsa
[DSA_DATAIN
+ sg_id
* 2] = nlen
;
772 targdata
->dsa
[DSA_DATAIN
+ sg_id
* 2 + 1] = naddr
;
773 resume_offset
= Ent_resume_pmm
;
776 else if (index
> Ent_patch_output_data
/4 &&
777 index
<= Ent_end_data_trans
/4) {
778 /* Dataout transfer phase */
779 u32 sg_id
, oaddr
, olen
, naddr
, nlen
;
782 sg_id
= (index
- Ent_patch_output_data
/4 - 4) / 2;
783 targdata
->data_out_jump
= hostdata
->script
[Ent_patch_output_data
/4+1] =
784 virt_to_bus(hostdata
->script
+ Ent_patch_output_data
/4 + sg_id
* 2 + 2);
785 olen
= targdata
->dsa
[DSA_DATAOUT
+ sg_id
* 2];
786 oaddr
= targdata
->dsa
[DSA_DATAOUT
+ sg_id
* 2 + 1];
787 residual
= datapath_residual (host
);
788 naddr
= NCR_read32(DNAD_REG
) - residual
;
789 nlen
= (NCR_read32(DBC_REG
) & 0x00ffffff) + residual
;
790 DEB(DEB_PMM
, printk("scsi%d: DOUT sg %d, old %08x/%08x, new %08x/%08x (%d)\n",
791 host
->host_no
, sg_id
, oaddr
, olen
, naddr
, nlen
, residual
));
792 if (oaddr
+olen
!= naddr
+nlen
) {
793 printk("scsi%d: PMM DOUT counts error: 0x%x + 0x%x != 0x%x + 0x%x",
794 host
->host_no
, oaddr
, olen
, naddr
, nlen
);
797 targdata
->dsa
[DSA_DATAOUT
+ sg_id
* 2] = nlen
;
798 targdata
->dsa
[DSA_DATAOUT
+ sg_id
* 2 + 1] = naddr
;
799 resume_offset
= Ent_resume_pmm
;
803 printk("scsi%d: Unexpected phase change to %s at index 0x%x\n",
804 host
->host_no
, sbcl_to_phase(sbcl
), index
);
805 /* resume_offset is zero, which will cause a host reset */
808 NCR_write8 (CTEST8_REG
, CTEST8_10_CLF
);
809 while (NCR_read8 (CTEST8_REG
) & CTEST8_10_CLF
);
811 return resume_offset
;
816 handle_script_int(struct Scsi_Host
* host
, Scsi_Cmnd
* cmd
)
818 struct sim710_hostdata
*hostdata
=
819 (struct sim710_hostdata
*)host
->hostdata
[0];
820 struct sim710_target
*targdata
= hostdata
->target
+ cmd
->target
;
821 u32 dsps
, resume_offset
= 0;
824 dsps
= NCR_read32(DSPS_REG
);
827 case A_int_cmd_complete
:
828 cmd
->result
= targdata
->dsa_status
[0];
830 targdata
->cur_cmd
= NULL
;
831 resume_offset
= Ent_reselect
;
833 case A_int_msg_sdtr1
:
834 resume_offset
= handle_sdtr(host
, cmd
,
835 Ent_resume_msgin1a
, Ent_resume_msgin1b
);
837 case A_int_msg_sdtr2
:
838 resume_offset
= handle_sdtr(host
, cmd
, 0, Ent_resume_msgin2b
);
840 case A_int_msg_sdtr3
:
841 resume_offset
= handle_sdtr(host
, cmd
, 0, Ent_resume_msgin3b
);
844 /* Disconnect before command - not expected */
845 targdata
->resume_offset
= Ent_resume_msgin1a
;
846 resume_offset
= Ent_reselect
;
849 /* Disconnect after command - just wait for a reselect */
850 targdata
->resume_offset
= Ent_resume_msgin2a
;
851 resume_offset
= Ent_reselect
;
854 /* Disconnect after the data phase */
855 targdata
->resume_offset
= Ent_resume_msgin3a
;
856 resume_offset
= Ent_reselect
;
858 case A_int_reselected
:
859 hostdata
->script
[Ent_patch_output_data
/4+1] = targdata
->data_out_jump
;
860 hostdata
->script
[Ent_patch_input_data
/4+1] = targdata
->data_in_jump
;
861 NCR_write32(DSA_REG
, virt_to_bus(targdata
->dsa
));
862 resume_offset
= targdata
->resume_offset
;
864 case A_int_data_bad_phase
:
865 sbcl
= NCR_read8(SBCL_REG
) & SBCL_PHASE_MASK
;
866 printk("scsi%d: int_data_bad_phase, phase %s (%x)\n",
867 host
->host_no
, sbcl_to_phase(sbcl
), sbcl
);
869 case A_int_bad_extmsg1a
:
870 case A_int_bad_extmsg1b
:
871 case A_int_bad_extmsg2a
:
872 case A_int_bad_extmsg2b
:
873 case A_int_bad_extmsg3a
:
874 case A_int_bad_extmsg3b
:
878 case A_int_cmd_bad_phase
:
879 case A_int_no_msgout1
:
880 case A_int_no_msgout2
:
881 case A_int_no_msgout3
:
882 case A_int_not_cmd_complete
:
883 case A_int_sel_no_ident
:
884 case A_int_sel_not_cmd
:
885 case A_int_status_not_msgin
:
886 case A_int_resel_not_msgin
:
890 sbcl
= NCR_read8(SBCL_REG
) & SBCL_PHASE_MASK
;
891 printk("scsi%d: Unimplemented script interrupt: %08x, phase %s\n",
892 host
->host_no
, dsps
, sbcl_to_phase(sbcl
));
894 /* resume_offset is zero, which will cause a host reset */
896 return resume_offset
;
900 /* A quick wrapper for sim710_intr_handle to grab the spin lock */
903 do_sim710_intr_handle(int irq
, void *dev_id
, struct pt_regs
*regs
)
907 spin_lock_irqsave(&io_request_lock
, flags
);
908 sim710_intr_handle(irq
, dev_id
, regs
);
909 spin_unlock_irqrestore(&io_request_lock
, flags
);
913 /* A "high" level interrupt handler */
916 sim710_intr_handle(int irq
, void *dev_id
, struct pt_regs
*regs
)
919 struct Scsi_Host
* host
= (struct Scsi_Host
*)dev_id
;
920 struct sim710_hostdata
*hostdata
= (struct sim710_hostdata
*)host
->hostdata
[0];
922 unsigned char istat
, dstat
;
923 unsigned char sstat0
;
924 u32 dsps
, resume_offset
= 0;
929 while ((istat
= NCR_read8(ISTAT_REG
)) & (ISTAT_SIP
|ISTAT_DIP
)) {
930 dsps
= NCR_read32(DSPS_REG
);
931 hostdata
->state
= STATE_HALTED
;
933 if (istat
& ISTAT_SIP
) {
934 sstat0
= NCR_read8(SSTAT0_REG
);
936 if (istat
& ISTAT_DIP
) {
937 udelay(10); /* Some comment somewhere about 10cycles
938 * between accesses to sstat0 and dstat ??? */
939 dstat
= NCR_read8(DSTAT_REG
);
941 DEB(DEB_INTS
, printk("scsi%d: Int %d, istat %02x, sstat0 %02x "
942 "dstat %02x, dsp [%04x], scratch %02x\n",
943 host
->host_no
, sim710_intrs
, istat
, sstat0
, dstat
,
944 (u32
*)(bus_to_virt(NCR_read32(DSP_REG
))) - hostdata
->script
,
945 NCR_read32(SCRATCH_REG
)));
946 if ((dstat
& DSTAT_SIR
) && dsps
== A_int_reselected
) {
947 /* Reselected. Identify the target from LCRC_REG, and
948 * update current command. If we were trying to select
949 * a device, then that command needs to go back on the
950 * issue_queue for later.
952 unsigned char lcrc
= NCR_read8(LCRC_REG_10
);
955 if (!(lcrc
& 0x7f)) {
956 printk("scsi%d: Reselected with LCRC = %02x\n",
957 host
->host_no
, lcrc
);
961 while (!(lcrc
& 1)) {
965 DEB(DEB_DISC
, printk("scsi%d: Reselected by ID %d\n",
967 if (hostdata
->running
) {
969 (void)NCR_read8(CTEST2_REG_700
);
971 DEB(DEB_DISC
, printk("scsi%d: Select of %d interrupted "
972 "by reselect from %d (%p)\n",
973 host
->host_no
, hostdata
->running
->target
,
974 id
, hostdata
->target
[id
].cur_cmd
));
975 cmd
= hostdata
->running
;
976 hostdata
->target
[cmd
->target
].cur_cmd
= NULL
;
977 cmd
->SCp
.ptr
= (unsigned char *) hostdata
->issue_queue
;
978 hostdata
->issue_queue
= cmd
;
980 cmd
= hostdata
->running
= hostdata
->target
[id
].cur_cmd
;
984 cmd
= hostdata
->running
;
987 printk("scsi%d: No active command!\n", host
->host_no
);
988 printk("scsi%d: Int %d, istat %02x, sstat0 %02x "
989 "dstat %02x, dsp [%04x], scratch %02x, dsps %08x\n",
990 host
->host_no
, sim710_intrs
, istat
, sstat0
, dstat
,
991 (u32
*)(bus_to_virt(NCR_read32(DSP_REG
))) - hostdata
->script
,
992 NCR_read32(SCRATCH_REG
), dsps
);
993 /* resume_offset is zero, which will cause a host reset */
995 else if (sstat0
& SSTAT0_700_STO
) {
996 DEB(DEB_TOUT
, printk("scsi%d: Selection timeout\n", host
->host_no
));
997 cmd
->result
= DID_NO_CONNECT
<< 16;
999 hostdata
->target
[cmd
->target
].cur_cmd
= NULL
;
1000 resume_offset
= Ent_reselect
;
1002 else if (dstat
& DSTAT_SIR
)
1003 resume_offset
= handle_script_int(host
, cmd
);
1004 else if (sstat0
& SSTAT0_MA
) {
1005 resume_offset
= handle_phase_mismatch(host
, cmd
);
1007 else if (sstat0
& (SSTAT0_MA
|SSTAT0_SGE
|SSTAT0_UDC
|SSTAT0_RST
|SSTAT0_PAR
)) {
1008 printk("scsi%d: Serious error, sstat0 = %02x\n", host
->host_no
,
1011 /* resume_offset is zero, which will cause a host reset */
1013 else if (dstat
& (DSTAT_BF
|DSTAT_ABRT
|DSTAT_SSI
|DSTAT_WTD
)) {
1014 printk("scsi%d: Serious error, dstat = %02x\n", host
->host_no
,
1017 /* resume_offset is zero, which will cause a host reset */
1019 else if (dstat
& DSTAT_IID
) {
1020 /* This can be due to a quick reselect while doing a WAIT
1023 resume_offset
= handle_idd(host
, cmd
);
1027 printk("scsi%d: Spurious interrupt!\n", host
->host_no
);
1028 /* resume_offset is zero, which will cause a host reset */
1032 if (resume_offset
) {
1033 if (resume_offset
== Ent_reselect
) {
1034 hostdata
->running
= NULL
;
1035 hostdata
->state
= STATE_IDLE
;
1038 hostdata
->state
= STATE_BUSY
;
1039 DEB(DEB_RESUME
, printk("scsi%d: Resuming at script[0x%x]\n",
1040 host
->host_no
, resume_offset
/4));
1041 #ifdef DEBUG_LIMIT_INTS
1042 if (sim710_intrs
< DEBUG_LIMIT_INTS
)
1044 NCR_write32(DSP_REG
, virt_to_bus(hostdata
->script
+resume_offset
/4));
1045 if (resume_offset
== Ent_reselect
)
1046 run_process_issue_queue(hostdata
);
1049 printk("scsi%d: Failed to handle interrupt. Failing commands "
1050 "and resetting SCSI bus and chip\n", host
->host_no
);
1051 mdelay(4000); /* Give chance to read screen!! */
1055 restore_flags(flags
);
1060 run_command (struct sim710_hostdata
*hostdata
, Scsi_Cmnd
*cmd
)
1062 struct Scsi_Host
*host
= cmd
->host
;
1063 struct sim710_target
*targdata
= hostdata
->target
+ cmd
->target
;
1064 int i
, datain
, dataout
, sg_start
;
1065 u32
*dip
, *dop
, dsa
;
1067 DEB(DEB_CMND
, printk("scsi%d: id%d starting ", host
->host_no
,
1069 DEB(DEB_CMND
, print_command(cmd
->cmnd
));
1071 switch (cmd
->cmnd
[0]) {
1078 case READ_BLOCK_LIMITS
:
1089 case TEST_UNIT_READY
:
1090 case ALLOW_MEDIUM_REMOVAL
:
1092 datain
= dataout
= 0;
1095 datain
= dataout
= 1;
1098 memcpy(targdata
->dsa_cdb
, cmd
->cmnd
, MAX_CMND
);
1100 targdata
->dsa_msgout
[0] =
1101 IDENTIFY((opt_nodisc
& (1<<cmd
->target
)) ? 0 : 1 ,0);
1102 if (hostdata
->negotiate
& (1 << cmd
->target
)) {
1103 if (opt_noneg
& (1 << cmd
->target
)) {
1104 hostdata
->negotiate
^= (1 << cmd
->target
);
1105 targdata
->dsa
[DSA_MSGOUT
] = 1;
1108 DEB(DEB_SYNC
, printk("scsi%d: Negotiating async transfers "
1110 host
->host_no
, cmd
->target
));
1111 memcpy(targdata
->dsa_msgout
+1, async_message
, sizeof(async_message
));
1112 targdata
->dsa
[DSA_MSGOUT
] = sizeof(async_message
) + 1;
1116 targdata
->dsa
[DSA_MSGOUT
] = 1;
1118 targdata
->dsa_msgin
[0] = 0xff;
1119 targdata
->dsa_status
[0] = 0xff;
1121 targdata
->dsa
[DSA_SELECT
] = (1 << cmd
->target
) << 16;
1122 targdata
->dsa
[DSA_MSGOUT
+1] = virt_to_bus(targdata
->dsa_msgout
);
1123 targdata
->dsa
[DSA_CMND
] = cmd
->cmd_len
;
1124 targdata
->dsa
[DSA_CMND
+1] = virt_to_bus(targdata
->dsa_cdb
);
1125 targdata
->dsa
[DSA_STATUS
] = 1;
1126 targdata
->dsa
[DSA_STATUS
+1] = virt_to_bus(targdata
->dsa_status
);
1127 targdata
->dsa
[DSA_MSGIN
] = 1;
1128 targdata
->dsa
[DSA_MSGIN
+1] = virt_to_bus(targdata
->dsa_msgin
);
1130 sg_start
= (MAX_SG
- (cmd
->use_sg
? cmd
->use_sg
: 1)) * 2;
1131 dip
= targdata
->dsa
+ DSA_DATAIN
+ sg_start
;
1132 dop
= targdata
->dsa
+ DSA_DATAOUT
+ sg_start
;
1134 for (i
= 0; cmd
->use_sg
? (i
< cmd
->use_sg
) : !i
; i
++) {
1135 u32 vbuf
= cmd
->use_sg
?
1136 (u32
)(((struct scatterlist
*)cmd
->buffer
)[i
].address
) :
1137 (u32
)(cmd
->request_buffer
);
1138 u32 bbuf
= virt_to_bus((void *)vbuf
);
1139 u32 cnt
= cmd
->use_sg
?
1140 ((struct scatterlist
*)cmd
->buffer
)[i
].length
:
1141 cmd
->request_bufflen
;
1144 #ifdef CONFIG_TP34V_SCSI
1145 cache_clear(virt_to_phys((void *)vbuf
), cnt
);
1151 #ifdef CONFIG_TP34V_SCSI
1152 cache_push(virt_to_phys((void *)vbuf
), cnt
);
1158 targdata
->data_out_jump
= hostdata
->script
[Ent_patch_output_data
/4+1] =
1159 virt_to_bus(hostdata
->script
+ Ent_patch_output_data
/4 + sg_start
+ 2);
1160 targdata
->data_in_jump
= hostdata
->script
[Ent_patch_input_data
/4+1] =
1161 virt_to_bus(hostdata
->script
+ Ent_patch_input_data
/4 + sg_start
+ 2);
1163 for (i
= 0, dsa
= virt_to_bus(targdata
->dsa
); i
< 4; i
++) {
1164 u32 v
= hostdata
->script
[Ent_patch_new_dsa
/4 + i
* 2];
1167 v
|= (dsa
& 0xff) << 8;
1168 hostdata
->script
[Ent_patch_new_dsa
/4 + i
* 2] = v
;
1171 hostdata
->running
= targdata
->cur_cmd
= cmd
;
1172 hostdata
->state
= STATE_BUSY
;
1174 NCR_write8(ISTAT_REG
, ISTAT_10_SIGP
);
1178 static volatile int process_issue_queue_running
= 0;
1180 static __inline__
void
1181 run_process_issue_queue(struct sim710_hostdata
*hostdata
)
1183 unsigned long flags
;
1186 if (!process_issue_queue_running
) {
1187 process_issue_queue_running
= 1;
1188 process_issue_queue(hostdata
, flags
);
1190 * process_issue_queue_running is cleared in process_issue_queue
1191 * once it can't do more work, and process_issue_queue exits with
1192 * interrupts disabled.
1195 restore_flags (flags
);
1200 * Function : process_issue_queue (hostdata, flags)
1202 * Purpose : Start next command for any idle target.
1204 * NOTE : process_issue_queue exits with interrupts *disabled*, so the
1205 * caller must reenable them if it desires.
1207 * NOTE : process_issue_queue should be called from both
1208 * sim710_queue_command() and from the interrupt handler
1209 * after command completion.
1213 process_issue_queue (struct sim710_hostdata
*hostdata
, unsigned long flags
)
1215 Scsi_Cmnd
*tmp
, *prev
;
1219 * We run (with interrupts disabled) until we're sure that none of
1220 * the host adapters have anything that can be done, at which point
1221 * we set process_issue_queue_running to 0 and exit.
1223 * Interrupts are enabled before doing various other internal
1224 * instructions, after we've decided that we need to run through
1230 cli(); /* Freeze request queues */
1232 if (hostdata
->issue_queue
) {
1233 if (hostdata
->state
== STATE_DISABLED
) {
1234 tmp
= (Scsi_Cmnd
*) hostdata
->issue_queue
;
1235 hostdata
->issue_queue
= (Scsi_Cmnd
*) tmp
->SCp
.ptr
;
1236 tmp
->result
= (DID_BAD_TARGET
<< 16);
1237 tmp
->scsi_done (tmp
);
1240 else if (hostdata
->state
== STATE_IDLE
) {
1241 for (tmp
= hostdata
->issue_queue
, prev
= NULL
; tmp
;
1242 prev
= tmp
, tmp
= (Scsi_Cmnd
*) tmp
->SCp
.ptr
) {
1243 if (hostdata
->target
[tmp
->target
].cur_cmd
== NULL
) {
1245 prev
->SCp
.ptr
= tmp
->SCp
.ptr
;
1247 hostdata
->issue_queue
= (Scsi_Cmnd
*) tmp
->SCp
.ptr
;
1248 tmp
->SCp
.ptr
= NULL
;
1249 run_command (hostdata
, tmp
);
1251 } /* if target/lun is not busy */
1252 } /* scan issue queue for work */
1253 } /* host is idle */
1254 } /* if hostdata->issue_queue */
1256 restore_flags (flags
);
1258 process_issue_queue_running
= 0;
1263 sim710_queuecommand(Scsi_Cmnd
* cmd
, void (*done
)(Scsi_Cmnd
*))
1265 struct Scsi_Host
*host
= cmd
->host
;
1266 struct sim710_hostdata
*hostdata
= (struct sim710_hostdata
*)host
->hostdata
[0];
1268 unsigned long flags
;
1271 /* Silently ignore luns other than zero! */
1272 cmd
->result
= (DID_BAD_TARGET
<< 16);
1277 DEB(DEB_CMND
, printk("scsi%d: id%d queuing ", host
->host_no
,
1279 DEB(DEB_CMND
, print_command(cmd
->cmnd
));
1281 cmd
->scsi_done
= done
;
1282 cmd
->host_scribble
= NULL
;
1283 cmd
->SCp
.ptr
= NULL
;
1284 cmd
->SCp
.buffer
= NULL
;
1289 if (ignore_ids
& (1 << cmd
->target
)) {
1290 printk("scsi%d: ignoring target %d\n", host
->host_no
, cmd
->target
);
1291 cmd
->result
= (DID_BAD_TARGET
<< 16);
1293 restore_flags (flags
);
1296 #ifdef DEBUG_LIMIT_INTS
1297 if (sim710_intrs
> DEBUG_LIMIT_INTS
) {
1298 cmd
->result
= (DID_BAD_TARGET
<< 16);
1300 restore_flags (flags
);
1304 if (cmd
->use_sg
> MAX_SG
)
1305 panic ("cmd->use_sg = %d\n", cmd
->use_sg
);
1307 if (!(hostdata
->issue_queue
) || (cmd
->cmnd
[0] == REQUEST_SENSE
)) {
1308 cmd
->SCp
.ptr
= (unsigned char *) hostdata
->issue_queue
;
1309 hostdata
->issue_queue
= cmd
;
1311 for (tmp
= hostdata
->issue_queue
; tmp
->SCp
.ptr
;
1312 tmp
= (Scsi_Cmnd
*) tmp
->SCp
.ptr
);
1313 tmp
->SCp
.ptr
= (unsigned char *) cmd
;
1315 restore_flags (flags
);
1316 run_process_issue_queue(hostdata
);
1322 sim710_detect(Scsi_Host_Template
* tpnt
)
1324 unsigned char irq_vector
;
1325 unsigned char scsi_id
;
1326 unsigned int base_addr
;
1327 struct Scsi_Host
* host
= NULL
;
1328 struct sim710_hostdata
*hostdata
;
1336 param_setup(sim710
);
1339 if (no_of_boards
< 0) {
1340 printk("sim710: NCR53C710 driver disabled\n");
1345 /* If board details have been specified via boot/module parameters,
1346 * then don't bother probing.
1348 if (no_of_boards
== 0) {
1351 int mca_53c710_ids
[] = MCA_53C710_IDS
;
1352 int *id_to_check
= mca_53c710_ids
;
1353 static int io_004f_by_pos
[] = MCA_004F_IO_PORTS
;
1354 static int irq_004f_by_pos
[] = MCA_004F_IRQS
;
1355 static int io_01bb_by_pos
[] = MCA_01BB_IO_PORTS
;
1356 static int irq_01bb_by_pos
[] = MCA_01BB_IRQS
;
1358 while ( *id_to_check
&& no_of_boards
< MAXBOARDS
) {
1362 if ((slot
= mca_find_adapter(*id_to_check
, 0)) != MCA_NOTFOUND
) {
1364 pos
[0] = mca_read_stored_pos(slot
, 2);
1365 pos
[1] = mca_read_stored_pos(slot
, 3);
1366 pos
[2] = mca_read_stored_pos(slot
, 4);
1369 * 01BB & 01BA port base by bits 7,6,5,4,3,2 in pos[2]
1371 * 000000 <disabled> 001010 0x2800
1372 * 000001 <invalid> 001011 0x2C00
1373 * 000010 0x0800 001100 0x3000
1374 * 000011 0x0C00 001101 0x3400
1375 * 000100 0x1000 001110 0x3800
1376 * 000101 0x1400 001111 0x3C00
1377 * 000110 0x1800 010000 0x4000
1378 * 000111 0x1C00 010001 0x4400
1379 * 001000 0x2000 010010 0x4800
1380 * 001001 0x2400 010011 0x4C00
1383 * 00F4 port base by bits 3,2,1 in pos[0]
1385 * 000 <disabled> 001 0x200
1386 * 010 0x300 011 0x400
1387 * 100 0x500 101 0x600
1389 * 01BB & 01BA IRQ is specified in pos[0] bits 7 and 6:
1394 * 00F4 IRQ specified by bits 6,5,4 in pos[0]
1400 if ( *id_to_check
== 0x01bb || *id_to_check
== 0x01ba ) {
1401 bases
[no_of_boards
] = io_01bb_by_pos
[(pos
[2] & 0xFC) >> 2];
1402 irq_vectors
[no_of_boards
] =
1403 irq_01bb_by_pos
[((pos
[0] & 0xC0) >> 6)];
1404 if (bases
[no_of_boards
] == 0x0000)
1405 printk("sim710: NCR53C710 Adapter ID 0x01bb is disabled.\n");
1408 if ( *id_to_check
== 0x01bb )
1409 mca_set_adapter_name( slot
,
1410 "NCR 3360/3430 SCSI SubSystem" );
1412 mca_set_adapter_name(slot
,
1413 "NCR Dual SIOP SCSI Host Adapter Board");
1416 else if ( *id_to_check
== 0x004f ) {
1417 bases
[no_of_boards
] = io_004f_by_pos
[((pos
[0] & 0x0E) >> 1)];
1418 irq_vectors
[no_of_boards
] =
1419 irq_004f_by_pos
[((pos
[0] & 0x70) >> 4) - 4];
1420 if (bases
[no_of_boards
] == 0x0000)
1421 printk("sim710: NCR53C710 Adapter ID 0x004f is disabled.\n");
1424 mca_set_adapter_name(slot
,
1425 "NCR 53c710 SCSI Host Adapter Board");
1434 if (!no_of_boards
) {
1435 printk("sim710: No NCR53C710 adapter found.\n");
1439 size
= sizeof(struct sim710_hostdata
);
1441 while (size
> (PAGE_SIZE
<< order
))
1443 size
= PAGE_SIZE
<< order
;
1445 DEB(DEB_ANY
, printk("sim710: hostdata %d bytes, size %d, order %d\n",
1446 sizeof(struct sim710_hostdata
), size
, order
));
1448 tpnt
->proc_name
= "sim710";
1450 for(indx
= 0; indx
< no_of_boards
; indx
++) {
1451 unsigned long page
= __get_free_pages(GFP_ATOMIC
, order
);
1454 printk(KERN_WARNING
"sim710: out of memory registering board %d.\n", indx
);
1457 host
= scsi_register(tpnt
, 4);
1460 host
->hostdata
[0] = page
;
1461 hostdata
= (struct sim710_hostdata
*)host
->hostdata
[0];
1462 memset(hostdata
, 0, size
);
1463 #ifdef CONFIG_TP34V_SCSI
1464 cache_push(virt_to_phys(hostdata
), size
);
1465 cache_clear(virt_to_phys(hostdata
), size
);
1466 kernel_set_cachemode((void *)hostdata
,size
,IOMAP_NOCACHE_SER
);
1469 base_addr
= bases
[indx
];
1470 irq_vector
= irq_vectors
[indx
];
1471 printk("sim710: Configuring Sim710 (SCSI-ID %d) at %x, IRQ %d\n",
1472 scsi_id
, base_addr
, irq_vector
);
1473 DEB(DEB_ANY
, printk("sim710: hostdata = %p (%d bytes), dsa0 = %p\n",
1474 hostdata
, sizeof(struct sim710_hostdata
),
1475 hostdata
->target
[0].dsa
));
1476 hostdata
->chip
= indx
;
1477 host
->irq
= irq_vector
;
1478 host
->this_id
= scsi_id
;
1479 host
->unique_id
= base_addr
;
1480 host
->base
= base_addr
;
1484 revision
= (NCR_read8(CTEST8_REG
) & 0xF0) >> 4;
1485 printk("scsi%d: Revision 0x%x\n",host
->host_no
,revision
);
1487 sim710_soft_reset(host
);
1489 sim710_driver_init(host
);
1491 #ifdef CONFIG_TP34V_SCSI
1492 if (request_irq(irq_vector
,do_sim710_intr_handle
, 0, "sim710", host
))
1494 if (request_irq(irq_vector
,do_sim710_intr_handle
, SA_INTERRUPT
, "sim710", host
))
1497 printk("scsi%d : IRQ%d not free, detaching\n",
1498 host
->host_no
, host
->irq
);
1500 scsi_unregister (host
);
1504 request_region((u32
)host
->base
, 64, "sim710");
1508 NCR_write32(DSP_REG
, virt_to_bus(hostdata
->script
+Ent_reselect
/4));
1509 hostdata
->state
= STATE_IDLE
;
1515 sim710_abort(Scsi_Cmnd
* cmd
)
1517 struct Scsi_Host
* host
= cmd
->host
;
1519 printk("scsi%d: Unable to abort command for target %d\n",
1520 host
->host_no
, cmd
->target
);
1525 * This is a device reset. Need to select and send a Bus Device Reset msg.
1529 sim710_dev_reset(Scsi_Cmnd
* SCpnt
)
1531 struct Scsi_Host
* host
= SCpnt
->host
;
1533 printk("scsi%d: Unable to send Bus Device Reset for target %d\n",
1534 host
->host_no
, SCpnt
->target
);
1539 * This is bus reset. We need to reset the bus and fail any active commands.
1543 sim710_bus_reset(Scsi_Cmnd
* SCpnt
)
1545 struct Scsi_Host
* host
= SCpnt
->host
;
1547 printk("scsi%d: Unable to do SCSI bus reset\n", host
->host_no
);
1552 full_reset(struct Scsi_Host
* host
)
1554 struct sim710_hostdata
*hostdata
= (struct sim710_hostdata
*)
1560 printk("scsi%d: dsp = %08x (script[0x%04x]), scratch = %08x\n",
1561 host
->host_no
, NCR_read32(DSP_REG
),
1562 ((u32
)bus_to_virt(NCR_read32(DSP_REG
)) - (u32
)hostdata
->script
)/4,
1563 NCR_read32(SCRATCH_REG
));
1565 for (target
= 0; target
< 7; target
++) {
1566 if ((cmd
= hostdata
->target
[target
].cur_cmd
)) {
1567 printk("scsi%d: Failing command for ID%d\n",
1568 host
->host_no
, target
);
1569 cmd
->result
= DID_RESET
<< 16;
1570 cmd
->scsi_done(cmd
);
1571 hostdata
->target
[target
].cur_cmd
= NULL
;
1575 sim710_soft_reset(host
);
1576 sim710_driver_init(host
);
1578 NCR_write32(DSP_REG
, virt_to_bus(hostdata
->script
+Ent_reselect
/4));
1579 hostdata
->state
= STATE_IDLE
;
1581 run_process_issue_queue(hostdata
);
1587 * This is host reset. We need to reset the chip and the bus.
1591 sim710_host_reset(Scsi_Cmnd
* SCpnt
)
1593 struct Scsi_Host
* host
= SCpnt
->host
;
1595 printk("scsi%d: >>>>>>>>>>>> Host reset <<<<<<<<<<<<\n", host
->host_no
);
1597 return full_reset(host
);
1603 sim710_release(struct Scsi_Host
*host
)
1605 free_irq(host
->irq
, host
);
1607 release_region((u32
)host
->base
, 64);
1614 static Scsi_Host_Template driver_template
= SIM710_SCSI
;
1616 #include "scsi_module.c"