Import 2.3.18pre1
[davej-history.git] / drivers / scsi / AM53C974.c
blobe4e289775d6529a255ebd176c9e9a736df7c7333
1 #include <linux/config.h>
2 #include <linux/module.h>
3 #include <linux/delay.h>
4 #include <linux/signal.h>
5 #include <linux/sched.h>
6 #include <linux/errno.h>
7 #include <linux/pci.h>
8 #include <linux/string.h>
9 #include <linux/blk.h>
10 #include <linux/init.h>
11 #include <linux/spinlock.h>
13 #include <asm/io.h>
14 #include <asm/system.h>
16 #include "scsi.h"
17 #include "hosts.h"
18 #include "AM53C974.h"
19 #include "constants.h"
20 #include "sd.h"
22 /* AM53/79C974 (PCscsi) driver release 0.5
24 * The architecture and much of the code of this device
25 * driver was originally developed by Drew Eckhardt for
26 * the NCR5380. The following copyrights apply:
27 * For the architecture and all pieces of code which can also be found
28 * in the NCR5380 device driver:
29 * Copyright 1993, Drew Eckhardt
30 * Visionary Computing
31 * (Unix and Linux consulting and custom programming)
32 * drew@colorado.edu
33 * +1 (303) 666-5836
35 * The AM53C974_nobios_detect code was originally developed by
36 * Robin Cutshaw (robin@xfree86.org) and is used here in a
37 * slightly modified form.
39 * PCI detection rewritten by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
41 * For the remaining code:
42 * Copyright 1994, D. Frieauff
43 * EMail: fri@rsx42sun0.dofn.de
44 * Phone: x49-7545-8-2256 , x49-7541-42305
48 * $Log: AM53C974.c,v $
51 #ifdef AM53C974_DEBUG
52 #define DEB(x) x
53 #ifdef AM53C974_DEBUG_KEYWAIT
54 #define KEYWAIT() AM53C974_keywait()
55 #else
56 #define KEYWAIT()
57 #endif
58 #ifdef AM53C974_DEBUG_INIT
59 #define DEB_INIT(x) x
60 #else
61 #define DEB_INIT(x)
62 #endif
63 #ifdef AM53C974_DEBUG_MSG
64 #define DEB_MSG(x) x
65 #else
66 #define DEB_MSG(x)
67 #endif
68 #ifdef AM53C974_DEB_RESEL
69 #define DEB_RESEL(x) x
70 #else
71 #define DEB_RESEL(x)
72 #endif
73 #ifdef AM53C974_DEBUG_QUEUE
74 #define DEB_QUEUE(x) x
75 #define LIST(x,y) {printk("LINE:%d Adding %p to %p\n", __LINE__, (void*)(x), (void*)(y)); if ((x)==(y)) udelay(5); }
76 #define REMOVE(w,x,y,z) {printk("LINE:%d Removing: %p->%p %p->%p \n", __LINE__, (void*)(w), (void*)(x), (void*)(y), (void*)(z)); if ((x)==(y)) udelay(5); }
77 #else
78 #define DEB_QUEUE(x)
79 #define LIST(x,y)
80 #define REMOVE(w,x,y,z)
81 #endif
82 #ifdef AM53C974_DEBUG_INFO
83 #define DEB_INFO(x) x
84 #else
85 #define DEB_INFO(x)
86 #endif
87 #ifdef AM53C974_DEBUG_LINKED
88 #define DEB_LINKED(x) x
89 #else
90 #define DEB_LINKED(x)
91 #endif
92 #ifdef AM53C974_DEBUG_INTR
93 #define DEB_INTR(x) x
94 #else
95 #define DEB_INTR(x)
96 #endif
97 #else
98 #define DEB_INIT(x)
99 #define DEB(x)
100 #define DEB_QUEUE(x)
101 #define LIST(x,y)
102 #define REMOVE(w,x,y,z)
103 #define DEB_INFO(x)
104 #define DEB_LINKED(x)
105 #define DEB_INTR(x)
106 #define DEB_MSG(x)
107 #define DEB_RESEL(x)
108 #define KEYWAIT()
109 #endif
110 #ifdef AM53C974_DEBUG_ABORT
111 #define DEB_ABORT(x) x
112 #else
113 #define DEB_ABORT(x)
114 #endif
116 #ifdef VERBOSE_AM53C974_DEBUG
117 #define VDEB(x) x
118 #else
119 #define VDEB(x)
120 #endif
122 #define INSIDE(x,l,h) ( ((x) >= (l)) && ((x) <= (h)) )
125 #include <scsi/scsicam.h>
127 /***************************************************************************************
128 * Default setting of the controller's SCSI id. Edit and uncomment this only if your *
129 * BIOS does not correctly initialize the controller's SCSI id. *
130 * If you don't get a warning during boot, it is correctly initialized. *
131 ****************************************************************************************/
132 /* #define AM53C974_SCSI_ID 7 */
134 /***************************************************************************************
135 * Default settings for sync. negotiation enable, transfer rate and sync. offset. *
136 * These settings can be replaced by LILO overrides (append) with the following syntax: *
137 * AM53C974=host-scsi-id, target-scsi-id, max-rate, max-offset *
138 * Sync. negotiation is disabled by default and will be enabled for those targets which *
139 * are specified in the LILO override *
140 ****************************************************************************************/
141 #define DEFAULT_SYNC_NEGOTIATION_ENABLED 0 /* 0 or 1 */
142 #define DEFAULT_RATE 5 /* MHz, min: 3; max: 10 */
143 #define DEFAULT_SYNC_OFFSET 0 /* bytes, min: 0; max: 15; use 0 for async. mode */
145 /***************************************************************************************
146 * If defined, don't allow targets to disconnect during commands. This will reduce *
147 * performance, but may be worthwhile if you suspect the driver of corrupting data when *
148 * a disconnect happens. *
149 ***************************************************************************************/
150 #define AM53C974_PROHIBIT_DISCONNECT
152 /* --------------------- don't edit below here --------------------- */
154 #define AM53C974_DRIVER_REVISION_MAJOR 0
155 #define AM53C974_DRIVER_REVISION_MINOR 5
156 #define SEPARATOR_LINE \
157 "--------------------------------------------------------------------------\n"
159 /* debug control */
160 /* #define AM53C974_DEBUG */
161 /* #define AM53C974_DEBUG_MSG */
162 /* #define AM53C974_DEBUG_KEYWAIT */
163 /* #define AM53C974_DEBUG_INIT */
164 /* #define AM53C974_DEBUG_QUEUE */
165 /* #define AM53C974_DEBUG_INFO */
166 /* #define AM53C974_DEBUG_LINKED */
167 /* #define VERBOSE_AM53C974_DEBUG */
168 /* #define AM53C974_DEBUG_INTR */
169 /* #define AM53C974_DEB_RESEL */
170 #define AM53C974_DEBUG_ABORT
171 /* #define AM53C974_OPTION_DEBUG_PROBE_ONLY */
173 /* special options/constants */
174 #define DEF_CLK 40 /* chip clock freq. in MHz */
175 #define MIN_PERIOD 4 /* for negotiation: min. number of clocks per cycle */
176 #define MAX_PERIOD 13 /* for negotiation: max. number of clocks per cycle */
177 #define MAX_OFFSET 15 /* for negotiation: max. offset (0=async) */
179 #define DEF_SCSI_TIMEOUT 245 /* STIMREG value, 40 Mhz */
180 #define DEF_STP 8 /* STPREG value assuming 5.0 MB/sec, FASTCLK, FASTSCSI */
181 #define DEF_SOF_RAD 0 /* REQ/ACK deassertion delay */
182 #define DEF_SOF_RAA 0 /* REQ/ACK assertion delay */
183 #define DEF_ETM 0 /* CNTLREG1, ext. timing mode */
184 #define DEF_PERE 1 /* CNTLREG1, parity error reporting */
185 #define DEF_CLKF 0 /* CLKFREG, 0=40 Mhz */
186 #define DEF_ENF 1 /* CNTLREG2, enable features */
187 #define DEF_ADIDCHK 0 /* CNTLREG3, additional ID check */
188 #define DEF_FASTSCSI 1 /* CNTLREG3, fast SCSI */
189 #define DEF_FASTCLK 1 /* CNTLREG3, fast clocking, 5 MB/sec at 40MHz chip clk */
190 #define DEF_GLITCH 1 /* CNTLREG4, glitch eater, 0=12ns, 1=35ns, 2=25ns, 3=off */
191 #define DEF_PWD 0 /* CNTLREG4, reduced power feature */
192 #define DEF_RAE 0 /* CNTLREG4, RAE active negation on REQ, ACK only */
193 #define DEF_RADE 1 /* 1CNTLREG4, active negation on REQ, ACK and data */
195 /*** SCSI block ***/
196 #define CTCLREG 0x00 /* r current transf. count, low byte */
197 #define CTCMREG 0x04 /* r current transf. count, middle byte */
198 #define CTCHREG 0x38 /* r current transf. count, high byte */
199 #define STCLREG 0x00 /* w start transf. count, low byte */
200 #define STCMREG 0x04 /* w start transf. count, middle byte */
201 #define STCHREG 0x38 /* w start transf. count, high byte */
202 #define FFREG 0x08 /* rw SCSI FIFO reg. */
203 #define STIMREG 0x14 /* w SCSI timeout reg. */
205 #define SDIDREG 0x10 /* w SCSI destination ID reg. */
206 #define SDIREG_MASK 0x07 /* mask */
208 #define STPREG 0x18 /* w synchronous transf. period reg. */
209 #define STPREG_STP 0x1F /* synchr. transfer period */
211 #define CLKFREG 0x24 /* w clock factor reg. */
212 #define CLKFREG_MASK 0x07 /* mask */
214 #define CMDREG 0x0C /* rw SCSI command reg. */
215 #define CMDREG_DMA 0x80 /* set DMA mode (set together with opcodes below) */
216 #define CMDREG_IT 0x10 /* information transfer */
217 #define CMDREG_ICCS 0x11 /* initiator command complete steps */
218 #define CMDREG_MA 0x12 /* message accepted */
219 #define CMDREG_TPB 0x98 /* transfer pad bytes, DMA mode only */
220 #define CMDREG_SATN 0x1A /* set ATN */
221 #define CMDREG_RATN 0x1B /* reset ATN */
222 #define CMDREG_SOAS 0x41 /* select without ATN steps */
223 #define CMDREG_SAS 0x42 /* select with ATN steps (1 msg byte) */
224 #define CMDREG_SASS 0x43 /* select with ATN and stop steps */
225 #define CMDREG_ESR 0x44 /* enable selection/reselection */
226 #define CMDREG_DSR 0x45 /* disable selection/reselection */
227 #define CMDREG_SA3S 0x46 /* select with ATN 3 steps (3 msg bytes) */
228 #define CMDREG_NOP 0x00 /* no operation */
229 #define CMDREG_CFIFO 0x01 /* clear FIFO */
230 #define CMDREG_RDEV 0x02 /* reset device */
231 #define CMDREG_RBUS 0x03 /* reset SCSI bus */
233 #define STATREG 0x10 /* r SCSI status reg. */
234 #define STATREG_INT 0x80 /* SCSI interrupt condition detected */
235 #define STATREG_IOE 0x40 /* SCSI illegal operation error detected */
236 #define STATREG_PE 0x20 /* SCSI parity error detected */
237 #define STATREG_CTZ 0x10 /* CTC reg decremented to zero */
238 #define STATREG_MSG 0x04 /* SCSI MSG phase (latched?) */
239 #define STATREG_CD 0x02 /* SCSI C/D phase (latched?) */
240 #define STATREG_IO 0x01 /* SCSI I/O phase (latched?) */
241 #define STATREG_PHASE 0x07 /* SCSI phase mask */
243 #define INSTREG 0x14 /* r interrupt status reg. */
244 #define INSTREG_SRST 0x80 /* SCSI reset detected */
245 #define INSTREG_ICMD 0x40 /* SCSI invalid command detected */
246 #define INSTREG_DIS 0x20 /* target disconnected or sel/resel timeout */
247 #define INSTREG_SR 0x10 /* device on bus has service request */
248 #define INSTREG_SO 0x08 /* successful operation */
249 #define INSTREG_RESEL 0x04 /* device reselected as initiator */
251 #define ISREG 0x18 /* r internal state reg. */
252 #define ISREG_SOF 0x08 /* synchronous offset flag (act. low) */
253 #define ISREG_IS 0x07 /* status of intermediate op. */
254 #define ISREG_OK_NO_STOP 0x04 /* selection successful */
255 #define ISREG_OK_STOP 0x01 /* selection successful */
257 #define CFIREG 0x1C /* r current FIFO/internal state reg. */
258 #define CFIREG_IS 0xE0 /* status of intermediate op. */
259 #define CFIREG_CF 0x1F /* number of bytes in SCSI FIFO */
261 #define SOFREG 0x1C /* w synchr. offset reg. */
262 #define SOFREG_RAD 0xC0 /* REQ/ACK deassertion delay (sync.) */
263 #define SOFREG_RAA 0x30 /* REQ/ACK assertion delay (sync.) */
264 #define SOFREG_SO 0x0F /* synch. offset (sync.) */
266 #define CNTLREG1 0x20 /* rw control register one */
267 #define CNTLREG1_ETM 0x80 /* set extended timing mode */
268 #define CNTLREG1_DISR 0x40 /* disable interrupt on SCSI reset */
269 #define CNTLREG1_PERE 0x10 /* enable parity error reporting */
270 #define CNTLREG1_SID 0x07 /* host adapter SCSI ID */
272 #define CNTLREG2 0x2C /* rw control register two */
273 #define CNTLREG2_ENF 0x40 /* enable features */
275 #define CNTLREG3 0x30 /* rw control register three */
276 #define CNTLREG3_ADIDCHK 0x80 /* additional ID check */
277 #define CNTLREG3_FASTSCSI 0x10 /* fast SCSI */
278 #define CNTLREG3_FASTCLK 0x08 /* fast SCSI clocking */
280 #define CNTLREG4 0x34 /* rw control register four */
281 #define CNTLREG4_GLITCH 0xC0 /* glitch eater */
282 #define CNTLREG4_PWD 0x20 /* reduced power feature */
283 #define CNTLREG4_RAE 0x08 /* write only, active negot. ctrl. */
284 #define CNTLREG4_RADE 0x04 /* active negot. ctrl. */
285 #define CNTLREG4_RES 0x10 /* reserved bit, must be 1 */
287 /*** DMA block ***/
288 #define DMACMD 0x40 /* rw command */
289 #define DMACMD_DIR 0x80 /* transfer direction (1=read from device) */
290 #define DMACMD_INTE_D 0x40 /* DMA transfer interrupt enable */
291 #define DMACMD_INTE_P 0x20 /* page transfer interrupt enable */
292 #define DMACMD_MDL 0x10 /* map to memory descriptor list */
293 #define DMACMD_DIAG 0x04 /* diagnostics, set to 0 */
294 #define DMACMD_IDLE 0x00 /* idle cmd */
295 #define DMACMD_BLAST 0x01 /* flush FIFO to memory */
296 #define DMACMD_ABORT 0x02 /* terminate DMA */
297 #define DMACMD_START 0x03 /* start DMA */
299 #define DMASTATUS 0x54 /* r status register */
300 #define DMASTATUS_BCMPLT 0x20 /* BLAST complete */
301 #define DMASTATUS_SCSIINT 0x10 /* SCSI interrupt pending */
302 #define DMASTATUS_DONE 0x08 /* DMA transfer terminated */
303 #define DMASTATUS_ABORT 0x04 /* DMA transfer aborted */
304 #define DMASTATUS_ERROR 0x02 /* DMA transfer error */
305 #define DMASTATUS_PWDN 0x02 /* power down indicator */
307 #define DMASTC 0x44 /* rw starting transfer count */
308 #define DMASPA 0x48 /* rw starting physical address */
309 #define DMAWBC 0x4C /* r working byte counter */
310 #define DMAWAC 0x50 /* r working address counter */
311 #define DMASMDLA 0x58 /* rw starting MDL address */
312 #define DMAWMAC 0x5C /* r working MDL counter */
314 /*** SCSI phases ***/
315 #define PHASE_MSGIN 0x07
316 #define PHASE_MSGOUT 0x06
317 #define PHASE_RES_1 0x05
318 #define PHASE_RES_0 0x04
319 #define PHASE_STATIN 0x03
320 #define PHASE_CMDOUT 0x02
321 #define PHASE_DATAIN 0x01
322 #define PHASE_DATAOUT 0x00
325 #define AM53C974_local_declare() unsigned long io_port
326 #define AM53C974_setio(instance) io_port = instance->io_port
327 #define AM53C974_read_8(addr) inb(io_port + (addr))
328 #define AM53C974_write_8(addr,x) outb((x), io_port + (addr))
329 #define AM53C974_read_16(addr) inw(io_port + (addr))
330 #define AM53C974_write_16(addr,x) outw((x), io_port + (addr))
331 #define AM53C974_read_32(addr) inl(io_port + (addr))
332 #define AM53C974_write_32(addr,x) outl((x), io_port + (addr))
334 #define AM53C974_poll_int() { do { statreg = AM53C974_read_8(STATREG); } \
335 while (!(statreg & STATREG_INT)) ; \
336 AM53C974_read_8(INSTREG) ; } /* clear int */
337 #define AM53C974_cfifo() (AM53C974_read_8(CFIREG) & CFIREG_CF)
339 /* These are "special" values for the tag parameter passed to AM53C974_select. */
340 #define TAG_NEXT -1 /* Use next free tag */
341 #define TAG_NONE -2 /* Establish I_T_L nexus instead of I_T_L_Q
342 * even on SCSI-II devices */
344 /************ LILO overrides *************/
345 typedef struct _override_t {
346 int host_scsi_id; /* SCSI id of the bus controller */
347 int target_scsi_id; /* SCSI id of target */
348 int max_rate; /* max. transfer rate */
349 int max_offset; /* max. sync. offset, 0 = asynchronous */
350 } override_t;
353 #ifdef AM53C974_DEBUG
354 static void AM53C974_print_phase(struct Scsi_Host *instance);
355 static void AM53C974_print_queues(struct Scsi_Host *instance);
356 #endif /* AM53C974_DEBUG */
357 static void AM53C974_print(struct Scsi_Host *instance);
358 static void AM53C974_keywait(void);
359 static __inline__ int AM53C974_pci_detect(Scsi_Host_Template * tpnt);
360 static int AM53C974_init(Scsi_Host_Template * tpnt, struct pci_dev *pdev);
361 static void AM53C974_config_after_reset(struct Scsi_Host *instance);
362 static __inline__ void initialize_SCp(Scsi_Cmnd * cmd);
363 static __inline__ void run_main(void);
364 static void AM53C974_main(void);
365 static void AM53C974_intr(int irq, void *dev_id, struct pt_regs *regs);
366 static void do_AM53C974_intr(int irq, void *dev_id, struct pt_regs *regs);
367 static void AM53C974_intr_disconnect(struct Scsi_Host *instance);
368 static int AM53C974_sync_neg(struct Scsi_Host *instance, int target, unsigned char *msg);
369 static __inline__ void AM53C974_set_async(struct Scsi_Host *instance, int target);
370 static __inline__ void AM53C974_set_sync(struct Scsi_Host *instance, int target);
371 static void AM53C974_information_transfer(struct Scsi_Host *instance,
372 unsigned char statreg, unsigned char isreg,
373 unsigned char instreg, unsigned char cfifo,
374 unsigned char dmastatus);
375 static int AM53C974_message(struct Scsi_Host *instance, Scsi_Cmnd * cmd, unsigned char msg);
376 static void AM53C974_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag);
377 static void AM53C974_intr_reselect(struct Scsi_Host *instance, unsigned char statreg);
378 static __inline__ void AM53C974_transfer_dma(struct Scsi_Host *instance, short dir,
379 unsigned long length, char *data);
380 static void AM53C974_dma_blast(struct Scsi_Host *instance, unsigned char dmastatus,
381 unsigned char statreg);
382 static void AM53C974_intr_bus_reset(struct Scsi_Host *instance);
384 static struct Scsi_Host *first_instance = NULL;
385 static Scsi_Host_Template *the_template = NULL;
386 static struct Scsi_Host *first_host = NULL; /* Head of list of AMD boards */
387 static volatile int main_running = 0;
388 static int commandline_current = 0;
389 override_t overrides[7] =
391 {-1, 0, 0, 0},}; /* LILO overrides */
393 struct proc_dir_entry proc_scsi_am53c974 =
395 PROC_SCSI_AM53C974, 8, "am53c974",
396 S_IFDIR | S_IRUGO | S_IXUGO, 2
399 #ifdef AM53C974_DEBUG
400 static int deb_stop = 1;
402 static struct {
403 unsigned char value;
404 char *name;
405 } phases[] = {
408 PHASE_DATAOUT, "DATAOUT"
409 }, {
410 PHASE_DATAIN, "DATAIN"
411 }, {
412 PHASE_CMDOUT, "CMDOUT"
415 PHASE_STATIN, "STATIN"
416 }, {
417 PHASE_MSGOUT, "MSGOUT"
418 }, {
419 PHASE_MSGIN, "MSGIN"
422 PHASE_RES_0, "RESERVED 0"
423 }, {
424 PHASE_RES_1, "RESERVED 1"
428 /**************************************************************************
429 * Function : void AM53C974_print_phase(struct Scsi_Host *instance)
431 * Purpose : print the current SCSI phase for debugging purposes
433 * Input : instance - which AM53C974
434 **************************************************************************/
435 static void AM53C974_print_phase(struct Scsi_Host *instance)
437 AM53C974_local_declare();
438 unsigned char statreg, latched;
439 int i;
440 AM53C974_setio(instance);
442 latched = (AM53C974_read_8(CNTLREG2)) & CNTLREG2_ENF;
443 statreg = AM53C974_read_8(STATREG);
444 for (i = 0; (phases[i].value != PHASE_RES_1) &&
445 (phases[i].value != (statreg & STATREG_PHASE)); ++i);
446 if (latched)
447 printk("scsi%d : phase %s, latched at end of last command\n", instance->host_no, phases[i].name);
448 else
449 printk("scsi%d : phase %s, real time\n", instance->host_no, phases[i].name);
452 /**************************************************************************
453 * Function : void AM53C974_print_queues(struct Scsi_Host *instance)
455 * Purpose : print commands in the various queues
457 * Inputs : instance - which AM53C974
458 **************************************************************************/
459 static void AM53C974_print_queues(struct Scsi_Host *instance)
461 unsigned long flags;
462 struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *) instance->hostdata;
463 Scsi_Cmnd *ptr;
465 printk("AM53C974: coroutine is%s running.\n", main_running ? "" : "n't");
467 save_flags(flags);
468 cli();
470 if (!hostdata->connected) {
471 printk("scsi%d: no currently connected command\n", instance->host_no);
472 } else {
473 print_Scsi_Cmnd((Scsi_Cmnd *) hostdata->connected);
475 if (!hostdata->sel_cmd) {
476 printk("scsi%d: no currently arbitrating command\n", instance->host_no);
477 } else {
478 print_Scsi_Cmnd((Scsi_Cmnd *) hostdata->sel_cmd);
481 printk("scsi%d: issue_queue ", instance->host_no);
482 if (!hostdata->issue_queue)
483 printk("empty\n");
484 else {
485 printk(":\n");
486 for (ptr = (Scsi_Cmnd *) hostdata->issue_queue; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble)
487 print_Scsi_Cmnd(ptr);
490 printk("scsi%d: disconnected_queue ", instance->host_no);
491 if (!hostdata->disconnected_queue)
492 printk("empty\n");
493 else {
494 printk(":\n");
495 for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble)
496 print_Scsi_Cmnd(ptr);
499 restore_flags(flags);
502 #endif /* AM53C974_DEBUG */
504 /**************************************************************************
505 * Function : void AM53C974_print(struct Scsi_Host *instance)
507 * Purpose : dump the chip registers for debugging purposes
509 * Input : instance - which AM53C974
510 **************************************************************************/
511 static void AM53C974_print(struct Scsi_Host *instance)
513 AM53C974_local_declare();
514 unsigned long flags;
515 unsigned long ctcreg, dmastc, dmaspa, dmawbc, dmawac;
516 unsigned char cmdreg, statreg, isreg, cfireg, cntlreg[4], dmacmd,
517 dmastatus;
518 AM53C974_setio(instance);
520 save_flags(flags);
521 cli();
522 ctcreg = AM53C974_read_8(CTCHREG) << 16;
523 ctcreg |= AM53C974_read_8(CTCMREG) << 8;
524 ctcreg |= AM53C974_read_8(CTCLREG);
525 cmdreg = AM53C974_read_8(CMDREG);
526 statreg = AM53C974_read_8(STATREG);
527 isreg = AM53C974_read_8(ISREG);
528 cfireg = AM53C974_read_8(CFIREG);
529 cntlreg[0] = AM53C974_read_8(CNTLREG1);
530 cntlreg[1] = AM53C974_read_8(CNTLREG2);
531 cntlreg[2] = AM53C974_read_8(CNTLREG3);
532 cntlreg[3] = AM53C974_read_8(CNTLREG4);
533 dmacmd = AM53C974_read_8(DMACMD);
534 dmastc = AM53C974_read_32(DMASTC);
535 dmaspa = AM53C974_read_32(DMASPA);
536 dmawbc = AM53C974_read_32(DMAWBC);
537 dmawac = AM53C974_read_32(DMAWAC);
538 dmastatus = AM53C974_read_8(DMASTATUS);
539 restore_flags(flags);
541 printk("AM53C974 register dump:\n");
542 printk("IO base: 0x%04lx; CTCREG: 0x%04lx; CMDREG: 0x%02x; STATREG: 0x%02x; ISREG: 0x%02x\n",
543 io_port, ctcreg, cmdreg, statreg, isreg);
544 printk("CFIREG: 0x%02x; CNTLREG1-4: 0x%02x; 0x%02x; 0x%02x; 0x%02x\n",
545 cfireg, cntlreg[0], cntlreg[1], cntlreg[2], cntlreg[3]);
546 printk("DMACMD: 0x%02x; DMASTC: 0x%04lx; DMASPA: 0x%04lx\n", dmacmd, dmastc, dmaspa);
547 printk("DMAWBC: 0x%04lx; DMAWAC: 0x%04lx; DMASTATUS: 0x%02x\n", dmawbc, dmawac, dmastatus);
548 printk("---------------------------------------------------------\n");
551 /**************************************************************************
552 * Function : void AM53C974_keywait(void)
554 * Purpose : wait until a key is pressed, if it was the 'r' key leave singlestep mode;
555 * this function is used for debugging only
557 * Input : none
558 **************************************************************************/
559 static void AM53C974_keywait(void)
561 unsigned long flags;
562 #ifdef AM53C974_DEBUG
563 int key;
565 if (!deb_stop)
566 return;
567 #endif
569 save_flags(flags);
570 cli();
571 while ((inb_p(0x64) & 0x01) != 0x01);
572 #ifdef AM53C974_DEBUG
573 key = inb(0x60);
574 if (key == 0x93)
575 deb_stop = 0; /* don't stop if 'r' was pressed */
576 #endif
577 restore_flags(flags);
580 /**************************************************************************
581 * Function : AM53C974_setup(char *str, int *ints)
583 * Purpose : LILO command line initialization of the overrides array,
585 * Inputs : str - unused, ints - array of integer parameters with ints[0]
586 * equal to the number of ints.
588 * NOTE : this function needs to be declared as an external function
589 * in init/main.c and included there in the bootsetups list
590 ***************************************************************************/
591 void AM53C974_setup(char *str, int *ints)
593 if (ints[0] < 4)
594 printk("AM53C974_setup: wrong number of parameters;\n correct syntax is: AM53C974=host-scsi-id, target-scsi-id, max-rate, max-offset\n");
595 else {
596 if (commandline_current < (sizeof(overrides) / sizeof(override_t))) {
597 if ((ints[1] < 0) || (ints[1] > 7) ||
598 (ints[2] < 0) || (ints[2] > 7) ||
599 (ints[1] == ints[2]) ||
600 (ints[3] < (DEF_CLK / MAX_PERIOD)) || (ints[3] > (DEF_CLK / MIN_PERIOD)) ||
601 (ints[4] < 0) || (ints[4] > MAX_OFFSET))
602 printk("AM53C974_setup: illegal parameter\n");
603 else {
604 overrides[commandline_current].host_scsi_id = ints[1];
605 overrides[commandline_current].target_scsi_id = ints[2];
606 overrides[commandline_current].max_rate = ints[3];
607 overrides[commandline_current].max_offset = ints[4];
608 commandline_current++;
610 } else
611 printk("AM53C974_setup: too many overrides\n");
615 #if defined (CONFIG_PCI)
616 /**************************************************************************
617 * Function : int AM53C974_pci_detect(Scsi_Host_Template *tpnt)
619 * Purpose : detects and initializes AM53C974 SCSI chips with PCI Bios
621 * Inputs : tpnt - host template
623 * Returns : number of host adapters detected
624 **************************************************************************/
625 static __inline__ int AM53C974_pci_detect(Scsi_Host_Template * tpnt)
627 int count = 0; /* number of boards detected */
628 struct pci_dev *pdev = NULL;
629 unsigned short command;
631 while ((pdev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SCSI, pdev))) {
632 pci_read_config_word(pdev, PCI_COMMAND, &command);
634 /* check whether device is I/O mapped -- should be */
635 if (!(command & PCI_COMMAND_IO))
636 continue;
638 /* PCI Spec 2.1 states that it is either the driver's or the PCI card's responsibility
639 to set the PCI Master Enable Bit if needed.
640 (from Mark Stockton <marks@schooner.sys.hou.compaq.com>) */
641 if (!(command & PCI_COMMAND_MASTER)) {
642 command |= PCI_COMMAND_MASTER;
643 printk("PCI Master Bit has not been set. Setting...\n");
644 pci_write_config_word(pdev, PCI_COMMAND, command);
646 /* everything seems OK now, so initialize */
647 if (AM53C974_init(tpnt, pdev))
648 count++;
650 return (count);
652 #endif
654 /**************************************************************************
655 * Function : int AM53C974_detect(Scsi_Host_Template *tpnt)
657 * Purpose : detects and initializes AM53C974 SCSI chips
659 * Inputs : tpnt - host template
661 * Returns : number of host adapters detected
662 **************************************************************************/
663 int __init AM53C974_detect(Scsi_Host_Template * tpnt)
665 int count = 0; /* number of boards detected */
667 tpnt->proc_dir = &proc_scsi_am53c974;
669 #if defined (CONFIG_PCI)
670 if (pci_present())
671 count = AM53C974_pci_detect(tpnt);
672 #endif
673 return (count);
676 /**************************************************************************
677 * Function : int AM53C974_init(Scsi_Host_Template *tpnt, struct pci_dev *pdev)
679 * Purpose : initializes instance and corresponding AM53/79C974 chip,
681 * Inputs : tpnt - template, pci_config - PCI configuration,
683 * Returns : 1 on success, 0 on failure.
685 * NOTE: If no override for the controller's SCSI id is given and AM53C974_SCSI_ID
686 * is not defined we assume that the SCSI address of this controller is correctly
687 * set up by the BIOS (as reflected by contents of register CNTLREG1).
688 * This is the only BIOS assistance we need.
689 **************************************************************************/
690 static int __init AM53C974_init(Scsi_Host_Template * tpnt, struct pci_dev *pdev)
692 AM53C974_local_declare();
693 int i, j;
694 struct Scsi_Host *instance, *search;
695 struct AM53C974_hostdata *hostdata;
697 #ifdef AM53C974_OPTION_DEBUG_PROBE_ONLY
698 printk("AM53C974: probe only enabled, aborting initialization\n");
699 return 0;
700 #endif
702 instance = scsi_register(tpnt, sizeof(struct AM53C974_hostdata));
703 hostdata = (struct AM53C974_hostdata *) instance->hostdata;
704 instance->base = NULL;
705 instance->io_port = pdev->resource[0].start;
706 instance->irq = pdev->irq;
707 instance->dma_channel = -1;
708 AM53C974_setio(instance);
710 #ifdef AM53C974_SCSI_ID
711 instance->this_id = AM53C974_SCSI_ID;
712 AM53C974_write_8(CNTLREG1, instance->this_id & CNTLREG1_SID);
713 #else
714 instance->this_id = AM53C974_read_8(CNTLREG1) & CNTLREG1_SID;
715 if (instance->this_id != 7)
716 printk("scsi%d: WARNING: unusual hostadapter SCSI id %d; please verify!\n",
717 instance->host_no, instance->this_id);
718 #endif
720 for (i = 0; i < sizeof(hostdata->msgout); i++) {
721 hostdata->msgout[i] = NOP;
722 hostdata->last_message[i] = NOP;
724 for (i = 0; i < 8; i++) {
725 hostdata->busy[i] = 0;
726 hostdata->sync_per[i] = DEF_STP;
727 hostdata->sync_off[i] = 0;
728 hostdata->sync_neg[i] = 0;
729 hostdata->sync_en[i] = DEFAULT_SYNC_NEGOTIATION_ENABLED;
730 hostdata->max_rate[i] = DEFAULT_RATE;
731 hostdata->max_offset[i] = DEFAULT_SYNC_OFFSET;
734 /* overwrite defaults by LILO overrides */
735 for (i = 0; i < commandline_current; i++) {
736 if (overrides[i].host_scsi_id == instance->this_id) {
737 j = overrides[i].target_scsi_id;
738 hostdata->sync_en[j] = 1;
739 hostdata->max_rate[j] = overrides[i].max_rate;
740 hostdata->max_offset[j] = overrides[i].max_offset;
744 hostdata->sel_cmd = NULL;
745 hostdata->connected = NULL;
746 hostdata->issue_queue = NULL;
747 hostdata->disconnected_queue = NULL;
748 hostdata->in_reset = 0;
749 hostdata->aborted = 0;
750 hostdata->selecting = 0;
751 hostdata->disconnecting = 0;
752 hostdata->dma_busy = 0;
754 /* Set up an interrupt handler if we aren't already sharing an IRQ with another board */
755 for (search = first_host;
756 search && (((the_template != NULL) && (search->hostt != the_template)) ||
757 (search->irq != instance->irq) || (search == instance));
758 search = search->next);
759 if (!search) {
760 if (request_irq(instance->irq, do_AM53C974_intr, SA_SHIRQ, "AM53C974", instance)) {
761 printk("scsi%d: IRQ%d not free, detaching\n", instance->host_no, instance->irq);
762 scsi_unregister(instance);
763 return 0;
765 } else {
766 printk("scsi%d: using interrupt handler previously installed for scsi%d\n",
767 instance->host_no, search->host_no);
770 if (!the_template) {
771 the_template = instance->hostt;
772 first_instance = instance;
774 /* do hard reset */
775 AM53C974_write_8(CMDREG, CMDREG_RDEV); /* reset device */
776 udelay(5);
777 AM53C974_write_8(CMDREG, CMDREG_NOP);
778 AM53C974_write_8(CNTLREG1, CNTLREG1_DISR | instance->this_id);
779 AM53C974_write_8(CMDREG, CMDREG_RBUS); /* reset SCSI bus */
780 udelay(10);
781 AM53C974_config_after_reset(instance);
782 mdelay(500);
783 return (1);
786 /*********************************************************************
787 * Function : AM53C974_config_after_reset(struct Scsi_Host *instance) *
789 * Purpose : initializes chip registers after reset *
791 * Inputs : instance - which AM53C974 *
793 * Returns : nothing *
794 **********************************************************************/
795 static void AM53C974_config_after_reset(struct Scsi_Host *instance)
797 AM53C974_local_declare();
798 AM53C974_setio(instance);
800 /* clear SCSI FIFO */
801 AM53C974_write_8(CMDREG, CMDREG_CFIFO);
803 /* configure device */
804 AM53C974_write_8(STIMREG, DEF_SCSI_TIMEOUT);
805 AM53C974_write_8(STPREG, DEF_STP & STPREG_STP);
806 AM53C974_write_8(SOFREG, (DEF_SOF_RAD << 6) | (DEF_SOF_RAA << 4));
807 AM53C974_write_8(CLKFREG, DEF_CLKF & CLKFREG_MASK);
808 AM53C974_write_8(CNTLREG1, (DEF_ETM << 7) | CNTLREG1_DISR | (DEF_PERE << 4) | instance->this_id);
809 AM53C974_write_8(CNTLREG2, (DEF_ENF << 6));
810 AM53C974_write_8(CNTLREG3, (DEF_ADIDCHK << 7) | (DEF_FASTSCSI << 4) | (DEF_FASTCLK << 3));
811 AM53C974_write_8(CNTLREG4, (DEF_GLITCH << 6) | (DEF_PWD << 5) | (DEF_RAE << 3) | (DEF_RADE << 2) | CNTLREG4_RES);
814 /***********************************************************************
815 * Function : const char *AM53C974_info(struct Scsi_Host *instance) *
817 * Purpose : return device driver information *
819 * Inputs : instance - which AM53C974 *
821 * Returns : info string *
822 ************************************************************************/
823 const char *AM53C974_info(struct Scsi_Host *instance)
825 static char info[100];
827 sprintf(info, "AM53/79C974 PCscsi driver rev. %d.%d; host I/O address: 0x%lx; irq: %d\n",
828 AM53C974_DRIVER_REVISION_MAJOR, AM53C974_DRIVER_REVISION_MINOR,
829 instance->io_port, instance->irq);
830 return (info);
833 /**************************************************************************
834 * Function : int AM53C974_command (Scsi_Cmnd *SCpnt) *
836 * Purpose : the unqueued SCSI command function, replaced by the *
837 * AM53C974_queue_command function *
839 * Inputs : SCpnt - pointer to command structure *
841 * Returns :status, see hosts.h for details *
842 ***************************************************************************/
843 int AM53C974_command(Scsi_Cmnd * SCpnt)
845 DEB(printk("AM53C974_command called\n"));
846 return 0;
849 /**************************************************************************
850 * Function : void initialize_SCp(Scsi_Cmnd *cmd) *
852 * Purpose : initialize the saved data pointers for cmd to point to the *
853 * start of the buffer. *
855 * Inputs : cmd - Scsi_Cmnd structure to have pointers reset. *
857 * Returns : nothing *
858 **************************************************************************/
859 static __inline__ void initialize_SCp(Scsi_Cmnd * cmd)
861 if (cmd->use_sg) {
862 cmd->SCp.buffer = (struct scatterlist *) cmd->buffer;
863 cmd->SCp.buffers_residual = cmd->use_sg - 1;
864 cmd->SCp.ptr = (char *) cmd->SCp.buffer->address;
865 cmd->SCp.this_residual = cmd->SCp.buffer->length;
866 } else {
867 cmd->SCp.buffer = NULL;
868 cmd->SCp.buffers_residual = 0;
869 cmd->SCp.ptr = (char *) cmd->request_buffer;
870 cmd->SCp.this_residual = cmd->request_bufflen;
874 /**************************************************************************
875 * Function : run_main(void) *
877 * Purpose : insure that the coroutine is running and will process our *
878 * request. main_running is checked/set here (in an inline *
879 * function rather than in AM53C974_main itself to reduce the *
880 * chances of stack overflow. *
883 * Inputs : none *
885 * Returns : nothing *
886 **************************************************************************/
887 static __inline__ void run_main(void)
889 unsigned long flags;
890 save_flags(flags);
891 cli();
892 if (!main_running) {
893 /* main_running is cleared in AM53C974_main once it can't do
894 more work, and AM53C974_main exits with interrupts disabled. */
895 main_running = 1;
896 AM53C974_main();
898 restore_flags(flags);
901 /**************************************************************************
902 * Function : int AM53C974_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
904 * Purpose : writes SCSI command into AM53C974 FIFO
906 * Inputs : cmd - SCSI command, done - function called on completion, with
907 * a pointer to the command descriptor.
909 * Returns : status, see hosts.h for details
911 * Side effects :
912 * cmd is added to the per instance issue_queue, with minor
913 * twiddling done to the host specific fields of cmd. If the
914 * main coroutine is not running, it is restarted.
915 **************************************************************************/
916 int AM53C974_queue_command(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
918 unsigned long flags;
919 struct Scsi_Host *instance = cmd->host;
920 struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *) instance->hostdata;
921 Scsi_Cmnd *tmp;
923 save_flags(flags);
924 cli();
925 DEB_QUEUE(printk(SEPARATOR_LINE));
926 DEB_QUEUE(printk("scsi%d: AM53C974_queue_command called\n", instance->host_no));
927 DEB_QUEUE(printk("cmd=%02x target=%02x lun=%02x bufflen=%d use_sg = %02x\n",
928 cmd->cmnd[0], cmd->target, cmd->lun, cmd->request_bufflen, cmd->use_sg));
930 /* We use the host_scribble field as a pointer to the next command in a queue */
931 cmd->host_scribble = NULL;
932 cmd->scsi_done = done;
933 cmd->result = 0;
934 cmd->device->disconnect = 0;
936 /* Insert the cmd into the issue queue. Note that REQUEST SENSE
937 * commands are added to the head of the queue since any command will
938 * clear the contingent allegiance condition that exists and the
939 * sense data is only guaranteed to be valid while the condition exists. */
940 if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
941 LIST(cmd, hostdata->issue_queue);
942 cmd->host_scribble = (unsigned char *) hostdata->issue_queue;
943 hostdata->issue_queue = cmd;
944 } else {
945 for (tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp->host_scribble;
946 tmp = (Scsi_Cmnd *) tmp->host_scribble);
947 LIST(cmd, tmp);
948 tmp->host_scribble = (unsigned char *) cmd;
951 DEB_QUEUE(printk("scsi%d : command added to %s of queue\n", instance->host_no,
952 (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail"));
954 /* Run the coroutine if it isn't already running. */
955 run_main();
956 restore_flags(flags);
957 return 0;
960 /**************************************************************************
961 * Function : AM53C974_main (void)
963 * Purpose : AM53C974_main is a coroutine that runs as long as more work can
964 * be done on the AM53C974 host adapters in a system. Both
965 * AM53C974_queue_command() and AM53C974_intr() will try to start it
966 * in case it is not running.
968 * NOTE : AM53C974_main exits with interrupts *disabled*, the caller should
969 * reenable them. This prevents reentrancy and kernel stack overflow.
970 **************************************************************************/
971 static void AM53C974_main(void)
973 AM53C974_local_declare();
974 unsigned long flags;
975 Scsi_Cmnd *tmp, *prev;
976 struct Scsi_Host *instance;
977 struct AM53C974_hostdata *hostdata;
978 int done;
980 /* We run (with interrupts disabled) until we're sure that none of
981 * the host adapters have anything that can be done, at which point
982 * we set main_running to 0 and exit. */
984 save_flags(flags);
985 cli(); /* Freeze request queues */
986 do {
987 done = 1;
988 for (instance = first_instance; instance && instance->hostt == the_template;
989 instance = instance->next) {
990 hostdata = (struct AM53C974_hostdata *) instance->hostdata;
991 AM53C974_setio(instance);
992 /* start to select target if we are not connected and not in the
993 selection process */
994 if (!hostdata->connected && !hostdata->sel_cmd) {
995 /* Search through the issue_queue for a command destined for a target
996 that is not busy. */
997 for (tmp = (Scsi_Cmnd *) hostdata->issue_queue, prev = NULL; tmp;
998 prev = tmp, tmp = (Scsi_Cmnd *) tmp->host_scribble) {
999 /* When we find one, remove it from the issue queue. */
1000 if (!(hostdata->busy[tmp->target] & (1 << tmp->lun))) {
1001 if (prev) {
1002 REMOVE(prev, (Scsi_Cmnd *) (prev->host_scribble), tmp,
1003 (Scsi_Cmnd *) (tmp->host_scribble));
1004 prev->host_scribble = tmp->host_scribble;
1005 } else {
1006 REMOVE(-1, hostdata->issue_queue, tmp, tmp->host_scribble);
1007 hostdata->issue_queue = (Scsi_Cmnd *) tmp->host_scribble;
1009 tmp->host_scribble = NULL;
1011 /* go into selection mode, disable reselection and wait for
1012 SO interrupt which will continue with the selection process */
1013 hostdata->selecting = 1;
1014 hostdata->sel_cmd = tmp;
1015 AM53C974_write_8(CMDREG, CMDREG_DSR);
1016 break;
1017 } /* if target/lun is not busy */
1018 } /* for */
1020 /* if (!hostdata->connected) */
1021 else {
1022 DEB(printk("main: connected; cmd = 0x%lx, sel_cmd = 0x%lx\n",
1023 (long) hostdata->connected, (long) hostdata->sel_cmd));
1025 } /* for instance */
1026 } while (!done);
1027 main_running = 0;
1028 restore_flags(flags);
1031 /************************************************************************
1032 * Function : AM53C974_intr(int irq, void *dev_id, struct pt_regs *regs) *
1034 * Purpose : interrupt handler *
1036 * Inputs : irq - interrupt line, regs - ? *
1038 * Returns : nothing *
1039 ************************************************************************/
1040 static void do_AM53C974_intr(int irq, void *dev_id, struct pt_regs *regs)
1042 unsigned long flags;
1044 spin_lock_irqsave(&io_request_lock, flags);
1045 AM53C974_intr(irq, dev_id, regs);
1046 spin_unlock_irqrestore(&io_request_lock, flags);
1049 /************************************************************************
1050 * Function : AM53C974_intr(int irq, void *dev_id, struct pt_regs *regs) *
1052 * Purpose : interrupt handler *
1054 * Inputs : irq - interrupt line, regs - ? *
1056 * Returns : nothing *
1057 ************************************************************************/
1058 static void AM53C974_intr(int irq, void *dev_id, struct pt_regs *regs)
1060 AM53C974_local_declare();
1061 struct Scsi_Host *instance;
1062 struct AM53C974_hostdata *hostdata;
1063 unsigned char cmdreg, dmastatus, statreg, isreg, instreg, cfifo;
1065 /* find AM53C974 hostadapter responsible for this interrupt */
1066 for (instance = first_instance; instance; instance = instance->next)
1067 if ((instance->irq == irq) && (instance->hostt == the_template))
1068 goto FOUND;
1069 return;
1071 /* found; now decode and process */
1072 FOUND:
1073 hostdata = (struct AM53C974_hostdata *) instance->hostdata;
1074 AM53C974_setio(instance);
1075 dmastatus = AM53C974_read_8(DMASTATUS);
1077 DEB_INTR(printk(SEPARATOR_LINE));
1078 DEB_INTR(printk("AM53C974 interrupt; dmastatus=0x%02x\n", dmastatus));
1079 KEYWAIT();
1081 /*** DMA related interrupts ***/
1082 if (hostdata->connected && (dmastatus & (DMASTATUS_ERROR | DMASTATUS_PWDN |
1083 DMASTATUS_ABORT))) {
1084 /* DMA error or POWERDOWN */
1085 printk("scsi%d: DMA error or powerdown; dmastatus: 0x%02x\n",
1086 instance->host_no, dmastatus);
1087 #ifdef AM53C974_DEBUG
1088 deb_stop = 1;
1089 #endif
1090 panic("scsi%d: cannot recover\n", instance->host_no);
1092 if (hostdata->connected && (dmastatus & DMASTATUS_DONE)) {
1093 /* DMA transfer done */
1094 unsigned long residual;
1095 unsigned long flags;
1096 save_flags(flags);
1097 cli();
1098 if (!(AM53C974_read_8(DMACMD) & DMACMD_DIR)) {
1099 do {
1100 dmastatus = AM53C974_read_8(DMASTATUS);
1101 residual = AM53C974_read_8(CTCLREG) | (AM53C974_read_8(CTCMREG) << 8) |
1102 (AM53C974_read_8(CTCHREG) << 16);
1103 residual += AM53C974_read_8(CFIREG) & CFIREG_CF;
1104 } while (!(dmastatus & DMASTATUS_SCSIINT) && residual);
1105 residual = AM53C974_read_8(CTCLREG) | (AM53C974_read_8(CTCMREG) << 8) |
1106 (AM53C974_read_8(CTCHREG) << 16);
1107 residual += AM53C974_read_8(CFIREG) & CFIREG_CF;
1108 } else
1109 residual = 0;
1110 hostdata->connected->SCp.ptr += hostdata->connected->SCp.this_residual - residual;
1111 hostdata->connected->SCp.this_residual = residual;
1113 AM53C974_write_8(DMACMD, DMACMD_IDLE);
1115 /* if service request missed before, process it now (ugly) */
1116 if (hostdata->dma_busy) {
1117 hostdata->dma_busy = 0;
1118 cmdreg = AM53C974_read_8(CMDREG);
1119 statreg = AM53C974_read_8(STATREG);
1120 isreg = AM53C974_read_8(ISREG);
1121 instreg = AM53C974_read_8(INSTREG);
1122 cfifo = AM53C974_cfifo();
1123 AM53C974_information_transfer(instance, statreg, isreg, instreg, cfifo,
1124 dmastatus);
1126 restore_flags(flags);
1128 if (!(dmastatus & DMASTATUS_SCSIINT)) {
1129 return;
1131 /*** SCSI related interrupts ***/
1132 cmdreg = AM53C974_read_8(CMDREG);
1133 statreg = AM53C974_read_8(STATREG);
1134 isreg = AM53C974_read_8(ISREG);
1135 instreg = AM53C974_read_8(INSTREG);
1136 cfifo = AM53C974_cfifo();
1138 DEB_INTR(printk("scsi%d: statreg: 0x%02x; isreg: 0x%02x; instreg: 0x%02x; cfifo: 0x%02x\n",
1139 instance->host_no, statreg, isreg, instreg, cfifo));
1141 if (statreg & STATREG_PE) {
1142 /* parity error */
1143 #ifdef AM53C974_DEBUG
1144 deb_stop = 1;
1145 #endif
1146 printk("scsi%d : PARITY error\n", instance->host_no);
1147 if (hostdata->connected)
1148 hostdata->sync_off[hostdata->connected->target] = 0; /* setup asynchronous transfer */
1149 hostdata->aborted = 1;
1151 if (statreg & STATREG_IOE) {
1152 /* illegal operation error */
1153 #ifdef AM53C974_DEBUG
1154 deb_stop = 1;
1155 #endif
1156 printk("scsi%d : ILLEGAL OPERATION error\n", instance->host_no);
1157 printk("cmdreg: 0x%02x; dmacmd: 0x%02x; statreg: 0x%02x; \n"
1158 "isreg: 0x%02x; instreg: 0x%02x; cfifo: 0x%02x\n",
1159 cmdreg, AM53C974_read_8(DMACMD), statreg, isreg, instreg, cfifo);
1161 if (hostdata->in_reset && (instreg & INSTREG_SRST)) {
1162 unsigned long flags;
1163 /* RESET INTERRUPT */
1164 #ifdef AM53C974_DEBUG
1165 deb_stop = 1;
1166 #endif
1167 DEB(printk("Bus reset interrupt received\n"));
1168 AM53C974_intr_bus_reset(instance);
1169 save_flags(flags);
1170 cli();
1171 if (hostdata->connected) {
1172 hostdata->connected->result = DID_RESET << 16;
1173 hostdata->connected->scsi_done((Scsi_Cmnd *) hostdata->connected);
1174 hostdata->connected = NULL;
1175 } else {
1176 if (hostdata->sel_cmd) {
1177 hostdata->sel_cmd->result = DID_RESET << 16;
1178 hostdata->sel_cmd->scsi_done((Scsi_Cmnd *) hostdata->sel_cmd);
1179 hostdata->sel_cmd = NULL;
1182 restore_flags(flags);
1183 if (hostdata->in_reset == 1)
1184 goto EXIT;
1185 else
1186 return;
1188 if (instreg & INSTREG_ICMD) {
1189 /* INVALID COMMAND INTERRUPT */
1190 #ifdef AM53C974_DEBUG
1191 deb_stop = 1;
1192 #endif
1193 printk("scsi%d: Invalid command interrupt\n", instance->host_no);
1194 printk("cmdreg: 0x%02x; dmacmd: 0x%02x; statreg: 0x%02x; dmastatus: 0x%02x; \n"
1195 "isreg: 0x%02x; instreg: 0x%02x; cfifo: 0x%02x\n",
1196 cmdreg, AM53C974_read_8(DMACMD), statreg, dmastatus, isreg, instreg, cfifo);
1197 panic("scsi%d: cannot recover\n", instance->host_no);
1199 if (instreg & INSTREG_DIS) {
1200 unsigned long flags;
1201 /* DISCONNECT INTERRUPT */
1202 DEB_INTR(printk("Disconnect interrupt received; "));
1203 save_flags(flags);
1204 cli();
1205 AM53C974_intr_disconnect(instance);
1206 restore_flags(flags);
1207 goto EXIT;
1209 if (instreg & INSTREG_RESEL) {
1210 unsigned long flags;
1211 /* RESELECTION INTERRUPT */
1212 DEB_INTR(printk("Reselection interrupt received\n"));
1213 save_flags(flags);
1214 cli();
1215 AM53C974_intr_reselect(instance, statreg);
1216 restore_flags(flags);
1217 goto EXIT;
1219 if (instreg & INSTREG_SO) {
1220 DEB_INTR(printk("Successful operation interrupt received\n"));
1221 if (hostdata->selecting) {
1222 unsigned long flags;
1223 DEB_INTR(printk("DSR completed, starting select\n"));
1224 save_flags(flags);
1225 cli();
1226 AM53C974_select(instance, (Scsi_Cmnd *) hostdata->sel_cmd,
1227 (hostdata->sel_cmd->cmnd[0] == REQUEST_SENSE) ?
1228 TAG_NONE : TAG_NEXT);
1229 hostdata->selecting = 0;
1230 AM53C974_set_sync(instance, hostdata->sel_cmd->target);
1231 restore_flags(flags);
1232 return;
1234 if (hostdata->sel_cmd != NULL) {
1235 if (((isreg & ISREG_IS) != ISREG_OK_NO_STOP) &&
1236 ((isreg & ISREG_IS) != ISREG_OK_STOP)) {
1237 unsigned long flags;
1238 /* UNSUCCESSFUL SELECTION */
1239 DEB_INTR(printk("unsuccessful selection\n"));
1240 save_flags(flags);
1241 cli();
1242 hostdata->dma_busy = 0;
1243 LIST(hostdata->sel_cmd, hostdata->issue_queue);
1244 hostdata->sel_cmd->host_scribble = (unsigned char *) hostdata->issue_queue;
1245 hostdata->issue_queue = hostdata->sel_cmd;
1246 hostdata->sel_cmd = NULL;
1247 hostdata->selecting = 0;
1248 restore_flags(flags);
1249 goto EXIT;
1250 } else {
1251 unsigned long flags;
1252 /* SUCCESSFUL SELECTION */
1253 DEB(printk("successful selection; cmd=0x%02lx\n", (long) hostdata->sel_cmd));
1254 save_flags(flags);
1255 cli();
1256 hostdata->dma_busy = 0;
1257 hostdata->disconnecting = 0;
1258 hostdata->connected = hostdata->sel_cmd;
1259 hostdata->sel_cmd = NULL;
1260 hostdata->selecting = 0;
1261 #ifdef SCSI2
1262 if (!hostdata->connected->device->tagged_queue)
1263 #endif
1264 hostdata->busy[hostdata->connected->target] |= (1 << hostdata->connected->lun);
1265 /* very strange -- use_sg is sometimes nonzero for request sense commands !! */
1266 if ((hostdata->connected->cmnd[0] == REQUEST_SENSE) && hostdata->connected->use_sg) {
1267 DEB(printk("scsi%d: REQUEST_SENSE command with nonzero use_sg\n", instance->host_no));
1268 KEYWAIT();
1269 hostdata->connected->use_sg = 0;
1271 initialize_SCp((Scsi_Cmnd *) hostdata->connected);
1272 hostdata->connected->SCp.phase = PHASE_CMDOUT;
1273 AM53C974_information_transfer(instance, statreg, isreg, instreg, cfifo, dmastatus);
1274 restore_flags(flags);
1275 return;
1277 } else {
1278 unsigned long flags;
1279 save_flags(flags);
1280 cli();
1281 AM53C974_information_transfer(instance, statreg, isreg, instreg, cfifo, dmastatus);
1282 restore_flags(flags);
1283 return;
1286 if (instreg & INSTREG_SR) {
1287 DEB_INTR(printk("Service request interrupt received, "));
1288 if (hostdata->connected) {
1289 unsigned long flags;
1290 DEB_INTR(printk("calling information_transfer\n"));
1291 save_flags(flags);
1292 cli();
1293 AM53C974_information_transfer(instance, statreg, isreg, instreg, cfifo, dmastatus);
1294 restore_flags(flags);
1295 } else {
1296 printk("scsi%d: weird: service request when no command connected\n", instance->host_no);
1297 AM53C974_write_8(CMDREG, CMDREG_CFIFO);
1298 } /* clear FIFO */
1299 return;
1301 EXIT:
1302 DEB_INTR(printk("intr: starting main\n"));
1303 run_main();
1304 DEB_INTR(printk("end of intr\n"));
1307 /**************************************************************************
1308 * Function : AM53C974_intr_disconnect(struct Scsi_Host *instance)
1310 * Purpose : manage target disconnection
1312 * Inputs : instance -- which AM53C974
1314 * Returns : nothing
1315 **************************************************************************/
1316 static void AM53C974_intr_disconnect(struct Scsi_Host *instance)
1318 AM53C974_local_declare();
1319 struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *) instance->hostdata;
1320 Scsi_Cmnd *cmd;
1321 AM53C974_setio(instance);
1323 if (hostdata->sel_cmd != NULL) {
1324 /* normal selection timeout, typical for nonexisting targets */
1325 cmd = (Scsi_Cmnd *) hostdata->sel_cmd;
1326 DEB_INTR(printk("bad target\n"));
1327 cmd->result = DID_BAD_TARGET << 16;
1328 goto EXIT_FINISHED;
1330 if (!hostdata->connected) {
1331 /* can happen if controller was reset, a device tried to reconnect,
1332 failed and disconnects now */
1333 AM53C974_write_8(CMDREG, CMDREG_CFIFO);
1334 return;
1336 if (hostdata->disconnecting) {
1337 /* target sent disconnect message, so we are prepared */
1338 cmd = (Scsi_Cmnd *) hostdata->connected;
1339 AM53C974_set_async(instance, cmd->target);
1340 DEB_INTR(printk("scsi%d : disc. from cmnd %d for ta %d, lun %d\n",
1341 instance->host_no, cmd->cmnd[0], cmd->target, cmd->lun));
1342 if (cmd->device->disconnect) {
1343 /* target wants to reselect later */
1344 DEB_INTR(printk("ok, re-enabling selection\n"));
1345 LIST(cmd, hostdata->disconnected_queue);
1346 cmd->host_scribble = (unsigned char *) hostdata->disconnected_queue;
1347 hostdata->disconnected_queue = cmd;
1348 DEB_QUEUE(printk("scsi%d : command for target %d lun %d this %d was moved from connected to"
1349 " the disconnected_queue\n", instance->host_no, cmd->target,
1350 cmd->lun, hostdata->disconnected_queue->SCp.this_residual));
1351 DEB_QUEUE(AM53C974_print_queues(instance));
1352 goto EXIT_UNFINISHED;
1353 } else {
1354 /* target does not want to reselect later, we are really finished */
1355 #ifdef AM53C974_DEBUG
1356 if (cmd->cmnd[0] == REQUEST_SENSE) {
1357 int i;
1358 printk("Request sense data dump:\n");
1359 for (i = 0; i < cmd->request_bufflen; i++) {
1360 printk("%02x ", *((char *) (cmd->request_buffer) + i));
1361 if (i && !(i % 16))
1362 printk("\n");
1364 printk("\n");
1366 #endif
1367 goto EXIT_FINISHED;
1368 } /* !cmd->device->disconnect */
1369 } /* if (hostdata->disconnecting) */
1370 /* no disconnect message received; unexpected disconnection */
1371 cmd = (Scsi_Cmnd *) hostdata->connected;
1372 if (cmd) {
1373 #ifdef AM53C974_DEBUG
1374 deb_stop = 1;
1375 #endif
1376 AM53C974_set_async(instance, cmd->target);
1377 printk("scsi%d: Unexpected disconnect; phase: %d; target: %d; this_residual: %d; buffers_residual: %d; message: %d\n",
1378 instance->host_no, cmd->SCp.phase, cmd->target, cmd->SCp.this_residual, cmd->SCp.buffers_residual,
1379 cmd->SCp.Message);
1380 printk("cmdreg: 0x%02x; statreg: 0x%02x; isreg: 0x%02x; cfifo: 0x%02x\n",
1381 AM53C974_read_8(CMDREG), AM53C974_read_8(STATREG), AM53C974_read_8(ISREG),
1382 AM53C974_read_8(CFIREG) & CFIREG_CF);
1384 if ((hostdata->last_message[0] == EXTENDED_MESSAGE) &&
1385 (hostdata->last_message[2] == EXTENDED_SDTR)) {
1386 /* sync. negotiation was aborted, setup asynchronous transfer with target */
1387 hostdata->sync_off[cmd->target] = 0;
1389 if (hostdata->aborted || hostdata->msgout[0] == ABORT)
1390 cmd->result = DID_ABORT << 16;
1391 else
1392 cmd->result = DID_ERROR << 16;
1393 goto EXIT_FINISHED;
1395 EXIT_FINISHED:
1396 hostdata->aborted = 0;
1397 hostdata->msgout[0] = NOP;
1398 hostdata->sel_cmd = NULL;
1399 hostdata->connected = NULL;
1400 hostdata->selecting = 0;
1401 hostdata->disconnecting = 0;
1402 hostdata->dma_busy = 0;
1403 hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
1404 AM53C974_write_8(CMDREG, CMDREG_CFIFO);
1405 DEB(printk("disconnect; issue_queue: 0x%lx, disconnected_queue: 0x%lx\n",
1406 (long) hostdata->issue_queue, (long) hostdata->disconnected_queue));
1407 cmd->scsi_done(cmd);
1409 if (!hostdata->selecting) {
1410 AM53C974_set_async(instance, cmd->target);
1411 AM53C974_write_8(CMDREG, CMDREG_ESR);
1412 } /* allow reselect */
1413 return;
1415 EXIT_UNFINISHED:
1416 hostdata->msgout[0] = NOP;
1417 hostdata->sel_cmd = NULL;
1418 hostdata->connected = NULL;
1419 hostdata->aborted = 0;
1420 hostdata->selecting = 0;
1421 hostdata->disconnecting = 0;
1422 hostdata->dma_busy = 0;
1423 DEB(printk("disconnect; issue_queue: 0x%lx, disconnected_queue: 0x%lx\n",
1424 (long) hostdata->issue_queue, (long) hostdata->disconnected_queue));
1425 if (!hostdata->selecting) {
1426 AM53C974_set_async(instance, cmd->target);
1427 AM53C974_write_8(CMDREG, CMDREG_ESR);
1428 } /* allow reselect */
1429 return;
1432 /**************************************************************************
1433 * Function : int AM53C974_sync_neg(struct Scsi_Host *instance, int target, unsigned char *msg)
1435 * Purpose : setup message string for sync. negotiation
1437 * Inputs : instance -- which AM53C974
1438 * target -- which SCSI target to deal with
1439 * msg -- input message string
1441 * Returns : 0 if parameters accepted or 1 if not accepted
1443 * Side effects: hostdata is changed
1445 * Note: we assume here that fastclk is enabled
1446 **************************************************************************/
1447 static int AM53C974_sync_neg(struct Scsi_Host *instance, int target, unsigned char *msg)
1449 AM53C974_local_declare();
1450 struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *) instance->hostdata;
1451 int period, offset, i, rate, rate_rem;
1452 AM53C974_setio(instance);
1454 period = (DEF_CLK * msg[3] * 8 + 1000) / 2000;
1455 if (period < MIN_PERIOD) {
1456 period = MIN_PERIOD;
1457 hostdata->msgout[3] = period / 4;
1458 } else if (period > MAX_PERIOD) {
1459 period = MAX_PERIOD;
1460 hostdata->msgout[3] = period / 4;
1461 } else
1462 hostdata->msgout[3] = msg[3];
1463 offset = msg[4];
1464 if (offset > MAX_OFFSET)
1465 offset = MAX_OFFSET;
1466 hostdata->msgout[4] = offset;
1467 hostdata->sync_per[target] = period;
1468 hostdata->sync_off[target] = offset;
1469 for (i = 0; i < 3; i++)
1470 hostdata->msgout[i] = msg[i];
1471 if ((hostdata->msgout[3] != msg[3]) || (msg[4] != offset))
1472 return (1);
1474 rate = DEF_CLK / period;
1475 rate_rem = 10 * (DEF_CLK - period * rate) / period;
1477 if (offset)
1478 printk("\ntarget %d: rate=%d.%d Mhz, synchronous, sync offset=%d bytes\n",
1479 target, rate, rate_rem, offset);
1480 else
1481 printk("\ntarget %d: rate=%d.%d Mhz, asynchronous\n", target, rate, rate_rem);
1483 return (0);
1486 /**************************************************************************
1487 * Function : AM53C974_set_async(struct Scsi_Host *instance, int target)
1489 * Purpose : put controller into async. mode
1491 * Inputs : instance -- which AM53C974
1492 * target -- which SCSI target to deal with
1494 * Returns : nothing
1495 **************************************************************************/
1496 static __inline__ void AM53C974_set_async(struct Scsi_Host *instance, int target)
1498 AM53C974_local_declare();
1499 struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *) instance->hostdata;
1500 AM53C974_setio(instance);
1502 AM53C974_write_8(STPREG, hostdata->sync_per[target]);
1503 AM53C974_write_8(SOFREG, (DEF_SOF_RAD << 6) | (DEF_SOF_RAA << 4));
1506 /**************************************************************************
1507 * Function : AM53C974_set_sync(struct Scsi_Host *instance, int target)
1509 * Purpose : put controller into sync. mode
1511 * Inputs : instance -- which AM53C974
1512 * target -- which SCSI target to deal with
1514 * Returns : nothing
1515 **************************************************************************/
1516 static __inline__ void AM53C974_set_sync(struct Scsi_Host *instance, int target)
1518 AM53C974_local_declare();
1519 struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *) instance->hostdata;
1520 AM53C974_setio(instance);
1522 AM53C974_write_8(STPREG, hostdata->sync_per[target]);
1523 AM53C974_write_8(SOFREG, (SOFREG_SO & hostdata->sync_off[target]) |
1524 (DEF_SOF_RAD << 6) | (DEF_SOF_RAA << 4));
1527 /***********************************************************************
1528 * Function : AM53C974_information_transfer(struct Scsi_Host *instance, *
1529 * unsigned char statreg, unsigned char isreg, *
1530 * unsigned char instreg, unsigned char cfifo, *
1531 * unsigned char dmastatus) *
1533 * Purpose : handle phase changes *
1535 * Inputs : instance - which AM53C974 *
1536 * statreg - status register *
1537 * isreg - internal state register *
1538 * instreg - interrupt status register *
1539 * cfifo - number of bytes in FIFO *
1540 * dmastatus - dma status register *
1542 * Returns : nothing *
1543 ************************************************************************/
1544 static void AM53C974_information_transfer(struct Scsi_Host *instance,
1545 unsigned char statreg, unsigned char isreg,
1546 unsigned char instreg, unsigned char cfifo,
1547 unsigned char dmastatus)
1549 AM53C974_local_declare();
1550 struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *) instance->hostdata;
1551 Scsi_Cmnd *cmd = (Scsi_Cmnd *) hostdata->connected;
1552 int ret, i, len, residual = -1;
1553 AM53C974_setio(instance);
1555 DEB_INFO(printk(SEPARATOR_LINE));
1556 switch (statreg & STATREG_PHASE) { /* scsi phase */
1557 case PHASE_DATAOUT:
1558 DEB_INFO(printk("Dataout phase; cmd=0x%lx, sel_cmd=0x%lx, this_residual=%d, buffers_residual=%d\n",
1559 (long) hostdata->connected, (long) hostdata->sel_cmd, cmd->SCp.this_residual, cmd->SCp.buffers_residual));
1560 cmd->SCp.phase = PHASE_DATAOUT;
1561 goto PHASE_DATA_IO;
1563 case PHASE_DATAIN:
1564 DEB_INFO(printk("Datain phase; cmd=0x%lx, sel_cmd=0x%lx, this_residual=%d, buffers_residual=%d\n",
1565 (long) hostdata->connected, (long) hostdata->sel_cmd, cmd->SCp.this_residual, cmd->SCp.buffers_residual));
1566 cmd->SCp.phase = PHASE_DATAIN;
1567 PHASE_DATA_IO:
1568 if (hostdata->aborted) {
1569 AM53C974_write_8(DMACMD, DMACMD_IDLE);
1570 AM53C974_write_8(CMDREG, CMDREG_CFIFO);
1571 AM53C974_write_8(CMDREG, CMDREG_SATN);
1572 return;
1574 if ((!cmd->SCp.this_residual) && cmd->SCp.buffers_residual) {
1575 cmd->SCp.buffer++;
1576 cmd->SCp.buffers_residual--;
1577 cmd->SCp.ptr = (unsigned char *) cmd->SCp.buffer->address;
1578 cmd->SCp.this_residual = cmd->SCp.buffer->length;
1580 if (cmd->SCp.this_residual) {
1581 if (!(AM53C974_read_8(DMACMD) & DMACMD_START)) {
1582 hostdata->dma_busy = 0;
1583 AM53C974_transfer_dma(instance, statreg & STATREG_IO,
1584 (unsigned long) cmd->SCp.this_residual,
1585 cmd->SCp.ptr);
1586 } else
1587 hostdata->dma_busy = 1;
1589 return;
1591 case PHASE_MSGIN:
1592 DEB_INFO(printk("Message-In phase; cmd=0x%lx, sel_cmd=0x%lx\n",
1593 (long) hostdata->connected, (long) hostdata->sel_cmd));
1594 AM53C974_set_async(instance, cmd->target);
1595 if (cmd->SCp.phase == PHASE_DATAIN)
1596 AM53C974_dma_blast(instance, dmastatus, statreg);
1597 if ((cmd->SCp.phase == PHASE_DATAOUT) && (AM53C974_read_8(DMACMD) & DMACMD_START)) {
1598 AM53C974_write_8(DMACMD, DMACMD_IDLE);
1599 residual = cfifo + (AM53C974_read_8(CTCLREG) | (AM53C974_read_8(CTCMREG) << 8) |
1600 (AM53C974_read_8(CTCHREG) << 16));
1601 cmd->SCp.ptr += cmd->SCp.this_residual - residual;
1602 cmd->SCp.this_residual = residual;
1603 if (cfifo) {
1604 AM53C974_write_8(CMDREG, CMDREG_CFIFO);
1605 cfifo = 0;
1608 if (cmd->SCp.phase == PHASE_STATIN) {
1609 while ((AM53C974_read_8(CFIREG) & CFIREG_CF) < 2);
1610 cmd->SCp.Status = AM53C974_read_8(FFREG);
1611 cmd->SCp.Message = AM53C974_read_8(FFREG);
1612 DEB_INFO(printk("Message-In phase; status=0x%02x, message=0x%02x\n",
1613 cmd->SCp.Status, cmd->SCp.Message));
1614 ret = AM53C974_message(instance, cmd, cmd->SCp.Message);
1615 } else {
1616 if (!cfifo) {
1617 AM53C974_write_8(CMDREG, CMDREG_IT);
1618 AM53C974_poll_int();
1619 cmd->SCp.Message = AM53C974_read_8(FFREG);
1621 ret = AM53C974_message(instance, cmd, cmd->SCp.Message);
1623 cmd->SCp.phase = PHASE_MSGIN;
1624 AM53C974_set_sync(instance, cmd->target);
1625 break;
1626 case PHASE_MSGOUT:
1627 DEB_INFO(printk("Message-Out phase; cfifo=%d; msgout[0]=0x%02x\n",
1628 AM53C974_read_8(CFIREG) & CFIREG_CF, hostdata->msgout[0]));
1629 AM53C974_write_8(DMACMD, DMACMD_IDLE);
1630 AM53C974_set_async(instance, cmd->target);
1631 for (i = 0; i < sizeof(hostdata->last_message); i++)
1632 hostdata->last_message[i] = hostdata->msgout[i];
1633 if ((hostdata->msgout[0] == 0) || INSIDE(hostdata->msgout[0], 0x02, 0x1F) ||
1634 INSIDE(hostdata->msgout[0], 0x80, 0xFF))
1635 len = 1;
1636 else {
1637 if (hostdata->msgout[0] == EXTENDED_MESSAGE) {
1638 #ifdef AM53C974_DEBUG_INFO
1639 printk("Extended message dump:\n");
1640 for (i = 0; i < hostdata->msgout[1] + 2; i++) {
1641 printk("%02x ", hostdata->msgout[i]);
1642 if (i && !(i % 16))
1643 printk("\n");
1645 printk("\n");
1646 #endif
1647 len = hostdata->msgout[1] + 2;
1648 } else
1649 len = 2;
1651 for (i = 0; i < len; i++)
1652 AM53C974_write_8(FFREG, hostdata->msgout[i]);
1653 AM53C974_write_8(CMDREG, CMDREG_IT);
1654 cmd->SCp.phase = PHASE_MSGOUT;
1655 hostdata->msgout[0] = NOP;
1656 AM53C974_set_sync(instance, cmd->target);
1657 break;
1659 case PHASE_CMDOUT:
1660 DEB_INFO(printk("Command-Out phase\n"));
1661 AM53C974_set_async(instance, cmd->target);
1662 for (i = 0; i < cmd->cmd_len; i++)
1663 AM53C974_write_8(FFREG, cmd->cmnd[i]);
1664 AM53C974_write_8(CMDREG, CMDREG_IT);
1665 cmd->SCp.phase = PHASE_CMDOUT;
1666 AM53C974_set_sync(instance, cmd->target);
1667 break;
1669 case PHASE_STATIN:
1670 DEB_INFO(printk("Status phase\n"));
1671 if (cmd->SCp.phase == PHASE_DATAIN)
1672 AM53C974_dma_blast(instance, dmastatus, statreg);
1673 AM53C974_set_async(instance, cmd->target);
1674 if (cmd->SCp.phase == PHASE_DATAOUT) {
1675 unsigned long residual;
1677 if (AM53C974_read_8(DMACMD) & DMACMD_START) {
1678 AM53C974_write_8(DMACMD, DMACMD_IDLE);
1679 residual = cfifo + (AM53C974_read_8(CTCLREG) | (AM53C974_read_8(CTCMREG) << 8) |
1680 (AM53C974_read_8(CTCHREG) << 16));
1681 cmd->SCp.ptr += cmd->SCp.this_residual - residual;
1682 cmd->SCp.this_residual = residual;
1684 if (cfifo) {
1685 AM53C974_write_8(CMDREG, CMDREG_CFIFO);
1686 cfifo = 0;
1689 cmd->SCp.phase = PHASE_STATIN;
1690 AM53C974_write_8(CMDREG, CMDREG_ICCS); /* command complete */
1691 break;
1693 case PHASE_RES_0:
1694 case PHASE_RES_1:
1695 #ifdef AM53C974_DEBUG
1696 deb_stop = 1;
1697 #endif
1698 DEB_INFO(printk("Reserved phase\n"));
1699 break;
1701 KEYWAIT();
1704 /******************************************************************************
1705 * Function : int AM53C974_message(struct Scsi_Host *instance, Scsi_Cmnd *cmd,
1706 * unsigned char msg)
1708 * Purpose : handle SCSI messages
1710 * Inputs : instance -- which AM53C974
1711 * cmd -- SCSI command the message belongs to
1712 * msg -- message id byte
1714 * Returns : 1 on success, 0 on failure.
1715 **************************************************************************/
1716 static int AM53C974_message(struct Scsi_Host *instance, Scsi_Cmnd * cmd,
1717 unsigned char msg)
1719 AM53C974_local_declare();
1720 static unsigned char extended_msg[10];
1721 unsigned char statreg;
1722 int len, ret = 0;
1723 unsigned char *p;
1724 #ifdef AM53C974_DEBUG_MSG
1725 int j;
1726 #endif
1727 struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *) instance->hostdata;
1728 AM53C974_setio(instance);
1730 DEB_MSG(printk(SEPARATOR_LINE));
1732 /* Linking lets us reduce the time required to get the
1733 * next command out to the device, hopefully this will
1734 * mean we don't waste another revolution due to the delays
1735 * required by ARBITRATION and another SELECTION.
1736 * In the current implementation proposal, low level drivers
1737 * merely have to start the next command, pointed to by
1738 * next_link, done() is called as with unlinked commands. */
1739 switch (msg) {
1740 #ifdef LINKED
1741 case LINKED_CMD_COMPLETE:
1742 case LINKED_FLG_CMD_COMPLETE:
1743 /* Accept message by releasing ACK */
1744 DEB_LINKED(printk("scsi%d : target %d lun %d linked command complete.\n",
1745 instance->host_no, cmd->target, cmd->lun));
1746 /* Sanity check : A linked command should only terminate with
1747 * one of these messages if there are more linked commands available. */
1748 if (!cmd->next_link) {
1749 printk("scsi%d : target %d lun %d linked command complete, no next_link\n"
1750 instance->host_no, cmd->target, cmd->lun);
1751 hostdata->aborted = 1;
1752 AM53C974_write_8(CMDREG, CMDREG_SATN);
1753 AM53C974_write_8(CMDREG, CMDREG_MA);
1754 break;
1756 if (hostdata->aborted) {
1757 DEB_ABORT(printk("ATN set for cmnd %d upon reception of LINKED_CMD_COMPLETE or"
1758 "LINKED_FLG_CMD_COMPLETE message\n", cmd->cmnd[0]));
1759 AM53C974_write_8(CMDREG, CMDREG_SATN);
1761 AM53C974_write_8(CMDREG, CMDREG_MA);
1763 initialize_SCp(cmd->next_link);
1764 /* The next command is still part of this process */
1765 cmd->next_link->tag = cmd->tag;
1766 cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
1767 DEB_LINKED(printk("scsi%d : target %d lun %d linked request done, calling scsi_done().\n",
1768 instance->host_no, cmd->target, cmd->lun));
1769 cmd->scsi_done(cmd);
1770 cmd = hostdata->connected;
1771 break;
1773 #endif /* def LINKED */
1775 case ABORT:
1776 case COMMAND_COMPLETE:
1777 DEB_MSG(printk("scsi%d: command complete message received; cmd %d for target %d, lun %d\n",
1778 instance->host_no, cmd->cmnd[0], cmd->target, cmd->lun));
1779 hostdata->disconnecting = 1;
1780 cmd->device->disconnect = 0;
1782 /* I'm not sure what the correct thing to do here is :
1784 * If the command that just executed is NOT a request
1785 * sense, the obvious thing to do is to set the result
1786 * code to the values of the stored parameters.
1787 * If it was a REQUEST SENSE command, we need some way
1788 * to differentiate between the failure code of the original
1789 * and the failure code of the REQUEST sense - the obvious
1790 * case is success, where we fall through and leave the result
1791 * code unchanged.
1793 * The non-obvious place is where the REQUEST SENSE failed */
1794 if (cmd->cmnd[0] != REQUEST_SENSE)
1795 cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
1796 else if (cmd->SCp.Status != GOOD)
1797 cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16);
1798 if (hostdata->aborted) {
1799 AM53C974_write_8(CMDREG, CMDREG_SATN);
1800 AM53C974_write_8(CMDREG, CMDREG_MA);
1801 DEB_ABORT(printk("ATN set for cmnd %d upon reception of ABORT or"
1802 "COMMAND_COMPLETE message\n", cmd->cmnd[0]));
1803 break;
1805 if ((cmd->cmnd[0] != REQUEST_SENSE) && (cmd->SCp.Status == CHECK_CONDITION)) {
1806 DEB_MSG(printk("scsi%d : performing request sense\n", instance->host_no));
1807 cmd->cmnd[0] = REQUEST_SENSE;
1808 cmd->cmnd[1] &= 0xe0;
1809 cmd->cmnd[2] = 0;
1810 cmd->cmnd[3] = 0;
1811 cmd->cmnd[4] = sizeof(cmd->sense_buffer);
1812 cmd->cmnd[5] = 0;
1813 cmd->SCp.buffer = NULL;
1814 cmd->SCp.buffers_residual = 0;
1815 cmd->SCp.ptr = (char *) cmd->sense_buffer;
1816 cmd->SCp.this_residual = sizeof(cmd->sense_buffer);
1817 LIST(cmd, hostdata->issue_queue);
1818 cmd->host_scribble = (unsigned char *) hostdata->issue_queue;
1819 hostdata->issue_queue = (Scsi_Cmnd *) cmd;
1820 DEB_MSG(printk("scsi%d : REQUEST SENSE added to head of issue queue\n", instance->host_no));
1822 /* Accept message by clearing ACK */
1823 AM53C974_write_8(CMDREG, CMDREG_MA);
1824 break;
1826 case MESSAGE_REJECT:
1827 DEB_MSG(printk("scsi%d: reject message received; cmd %d for target %d, lun %d\n",
1828 instance->host_no, cmd->cmnd[0], cmd->target, cmd->lun));
1829 switch (hostdata->last_message[0]) {
1830 case EXTENDED_MESSAGE:
1831 if (hostdata->last_message[2] == EXTENDED_SDTR) {
1832 /* sync. negotiation was rejected, setup asynchronous transfer with target */
1833 printk("\ntarget %d: rate=%d Mhz, asynchronous (sync. negotiation rejected)\n",
1834 cmd->target, DEF_CLK / DEF_STP);
1835 hostdata->sync_off[cmd->target] = 0;
1836 hostdata->sync_per[cmd->target] = DEF_STP;
1838 break;
1839 case HEAD_OF_QUEUE_TAG:
1840 case ORDERED_QUEUE_TAG:
1841 case SIMPLE_QUEUE_TAG:
1842 cmd->device->tagged_queue = 0;
1843 hostdata->busy[cmd->target] |= (1 << cmd->lun);
1844 break;
1845 default:
1846 break;
1848 if (hostdata->aborted)
1849 AM53C974_write_8(CMDREG, CMDREG_SATN);
1850 AM53C974_write_8(CMDREG, CMDREG_MA);
1851 break;
1853 case DISCONNECT:
1854 DEB_MSG(printk("scsi%d: disconnect message received; cmd %d for target %d, lun %d\n",
1855 instance->host_no, cmd->cmnd[0], cmd->target, cmd->lun));
1856 cmd->device->disconnect = 1;
1857 hostdata->disconnecting = 1;
1858 AM53C974_write_8(CMDREG, CMDREG_MA); /* Accept message by clearing ACK */
1859 break;
1861 case SAVE_POINTERS:
1862 case RESTORE_POINTERS:
1863 DEB_MSG(printk("scsi%d: save/restore pointers message received; cmd %d for target %d, lun %d\n",
1864 instance->host_no, cmd->cmnd[0], cmd->target, cmd->lun));
1865 /* The SCSI data pointer is *IMPLICITLY* saved on a disconnect
1866 * operation, in violation of the SCSI spec so we can safely
1867 * ignore SAVE/RESTORE pointers calls.
1869 * Unfortunately, some disks violate the SCSI spec and
1870 * don't issue the required SAVE_POINTERS message before
1871 * disconnecting, and we have to break spec to remain
1872 * compatible. */
1873 if (hostdata->aborted) {
1874 DEB_ABORT(printk("ATN set for cmnd %d upon reception of SAVE/REST. POINTERS message\n",
1875 cmd->cmnd[0]));
1876 AM53C974_write_8(CMDREG, CMDREG_SATN);
1878 AM53C974_write_8(CMDREG, CMDREG_MA);
1879 break;
1881 case EXTENDED_MESSAGE:
1882 DEB_MSG(printk("scsi%d: extended message received; cmd %d for target %d, lun %d\n",
1883 instance->host_no, cmd->cmnd[0], cmd->target, cmd->lun));
1884 /* Extended messages are sent in the following format :
1885 * Byte
1886 * 0 EXTENDED_MESSAGE == 1
1887 * 1 length (includes one byte for code, doesn't include first two bytes)
1888 * 2 code
1889 * 3..length+1 arguments
1891 /* BEWARE!! THIS CODE IS EXTREMELY UGLY */
1892 extended_msg[0] = EXTENDED_MESSAGE;
1893 AM53C974_read_8(INSTREG); /* clear int */
1894 AM53C974_write_8(CMDREG, CMDREG_MA); /* ack. msg byte, then wait for SO */
1895 AM53C974_poll_int();
1896 /* get length */
1897 AM53C974_write_8(CMDREG, CMDREG_IT);
1898 AM53C974_poll_int();
1899 AM53C974_write_8(CMDREG, CMDREG_MA); /* ack. msg byte, then wait for SO */
1900 AM53C974_poll_int();
1901 extended_msg[1] = len = AM53C974_read_8(FFREG); /* get length */
1902 p = extended_msg + 2;
1903 /* read the remaining (len) bytes */
1904 while (len) {
1905 AM53C974_write_8(CMDREG, CMDREG_IT);
1906 AM53C974_poll_int();
1907 if (len > 1) {
1908 AM53C974_write_8(CMDREG, CMDREG_MA); /* ack. msg byte, then wait for SO */
1909 AM53C974_poll_int();
1911 *p = AM53C974_read_8(FFREG);
1912 p++;
1913 len--;
1916 #ifdef AM53C974_DEBUG_MSG
1917 printk("scsi%d: received extended message: ", instance->host_no);
1918 for (j = 0; j < extended_msg[1] + 2; j++) {
1919 printk("0x%02x ", extended_msg[j]);
1920 if (j && !(j % 16))
1921 printk("\n");
1923 printk("\n");
1924 #endif
1926 /* check message */
1927 if (extended_msg[2] == EXTENDED_SDTR)
1928 ret = AM53C974_sync_neg(instance, cmd->target, extended_msg);
1929 if (ret || hostdata->aborted)
1930 AM53C974_write_8(CMDREG, CMDREG_SATN);
1932 AM53C974_write_8(CMDREG, CMDREG_MA);
1933 break;
1935 default:
1936 printk("scsi%d: unknown message 0x%02x received\n", instance->host_no, msg);
1937 #ifdef AM53C974_DEBUG
1938 deb_stop = 1;
1939 #endif
1940 /* reject message */
1941 hostdata->msgout[0] = MESSAGE_REJECT;
1942 AM53C974_write_8(CMDREG, CMDREG_SATN);
1943 AM53C974_write_8(CMDREG, CMDREG_MA);
1944 return (0);
1945 break;
1947 } /* switch (msg) */
1948 KEYWAIT();
1949 return (1);
1952 /**************************************************************************
1953 * Function : AM53C974_select(struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag)
1955 * Purpose : try to establish nexus for the command;
1956 * start sync negotiation via start stop and transfer the command in
1957 * cmdout phase in case of an inquiry or req. sense command with no
1958 * sync. neg. performed yet
1960 * Inputs : instance -- which AM53C974
1961 * cmd -- command which requires the selection
1962 * tag -- tagged queueing
1964 * Returns : nothing
1966 * Note: this function initializes the selection process, which is continued
1967 * in the interrupt handler
1968 **************************************************************************/
1969 static void AM53C974_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag)
1971 AM53C974_local_declare();
1972 struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *) instance->hostdata;
1973 unsigned char cfifo, tmp[3];
1974 unsigned int i, len, cmd_size = COMMAND_SIZE(cmd->cmnd[0]);
1975 AM53C974_setio(instance);
1977 cfifo = AM53C974_cfifo();
1978 if (cfifo) {
1979 printk("scsi%d: select error; %d residual bytes in FIFO\n", instance->host_no, cfifo);
1980 AM53C974_write_8(CMDREG, CMDREG_CFIFO); /* clear FIFO */
1982 #ifdef AM53C974_PROHIBIT_DISCONNECT
1983 tmp[0] = IDENTIFY(0, cmd->lun);
1984 #else
1985 tmp[0] = IDENTIFY(1, cmd->lun);
1986 #endif
1988 #ifdef SCSI2
1989 if (cmd->device->tagged_queue && (tag != TAG_NONE)) {
1990 tmp[1] = SIMPLE_QUEUE_TAG;
1991 if (tag == TAG_NEXT) {
1992 /* 0 is TAG_NONE, used to imply no tag for this command */
1993 if (cmd->device->current_tag == 0)
1994 cmd->device->current_tag = 1;
1995 cmd->tag = cmd->device->current_tag;
1996 cmd->device->current_tag++;
1997 } else
1998 cmd->tag = (unsigned char) tag;
1999 tmp[2] = cmd->tag;
2000 hostdata->last_message[0] = SIMPLE_QUEUE_TAG;
2001 len = 3;
2002 AM53C974_write_8(FFREG, tmp[0]);
2003 AM53C974_write_8(FFREG, tmp[1]);
2004 AM53C974_write_8(FFREG, tmp[2]);
2005 } else
2006 #endif /* def SCSI2 */
2008 len = 1;
2009 AM53C974_write_8(FFREG, tmp[0]);
2010 cmd->tag = 0;
2013 /* in case of an inquiry or req. sense command with no sync. neg performed yet, we start
2014 sync negotiation via start stops and transfer the command in cmdout phase */
2015 if (((cmd->cmnd[0] == INQUIRY) || (cmd->cmnd[0] == REQUEST_SENSE)) &&
2016 !(hostdata->sync_neg[cmd->target]) && hostdata->sync_en[cmd->target]) {
2017 hostdata->sync_neg[cmd->target] = 1;
2018 hostdata->msgout[0] = EXTENDED_MESSAGE;
2019 hostdata->msgout[1] = 3;
2020 hostdata->msgout[2] = EXTENDED_SDTR;
2021 hostdata->msgout[3] = 250 / (int) hostdata->max_rate[cmd->target];
2022 hostdata->msgout[4] = hostdata->max_offset[cmd->target];
2023 len += 5;
2025 AM53C974_write_8(SDIDREG, SDIREG_MASK & cmd->target); /* setup dest. id */
2026 AM53C974_write_8(STIMREG, DEF_SCSI_TIMEOUT); /* setup timeout reg */
2027 switch (len) {
2028 case 1:
2029 for (i = 0; i < cmd_size; i++)
2030 AM53C974_write_8(FFREG, cmd->cmnd[i]);
2031 AM53C974_write_8(CMDREG, CMDREG_SAS); /* select with ATN, 1 msg byte */
2032 hostdata->msgout[0] = NOP;
2033 break;
2034 case 3:
2035 for (i = 0; i < cmd_size; i++)
2036 AM53C974_write_8(FFREG, cmd->cmnd[i]);
2037 AM53C974_write_8(CMDREG, CMDREG_SA3S); /* select with ATN, 3 msg bytes */
2038 hostdata->msgout[0] = NOP;
2039 break;
2040 default:
2041 AM53C974_write_8(CMDREG, CMDREG_SASS); /* select with ATN, stop steps; continue in message out phase */
2042 break;
2046 /**************************************************************************
2047 * Function : AM53C974_intr_select(struct Scsi_Host *instance, unsigned char statreg)
2049 * Purpose : handle reselection
2051 * Inputs : instance -- which AM53C974
2052 * statreg -- status register
2054 * Returns : nothing
2056 * side effects: manipulates hostdata
2057 **************************************************************************/
2058 static void AM53C974_intr_reselect(struct Scsi_Host *instance, unsigned char statreg)
2060 AM53C974_local_declare();
2061 struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *) instance->hostdata;
2062 unsigned char cfifo, msg[3], lun, t, target = 0;
2063 #ifdef SCSI2
2064 unsigned char tag;
2065 #endif
2066 Scsi_Cmnd *tmp = NULL, *prev;
2067 AM53C974_setio(instance);
2069 cfifo = AM53C974_cfifo();
2071 if (hostdata->selecting) {
2072 /* caught reselect interrupt in selection process;
2073 put selecting command back into the issue queue and continue with the
2074 reselecting command */
2075 DEB_RESEL(printk("AM53C974_intr_reselect: in selection process\n"));
2076 LIST(hostdata->sel_cmd, hostdata->issue_queue);
2077 hostdata->sel_cmd->host_scribble = (unsigned char *) hostdata->issue_queue;
2078 hostdata->issue_queue = hostdata->sel_cmd;
2079 hostdata->sel_cmd = NULL;
2080 hostdata->selecting = 0;
2082 /* 2 bytes must be in the FIFO now */
2083 if (cfifo != 2) {
2084 printk("scsi %d: error: %d bytes in fifo, 2 expected\n", instance->host_no, cfifo);
2085 hostdata->aborted = 1;
2086 goto EXIT_ABORT;
2088 /* determine target which reselected */
2089 t = AM53C974_read_8(FFREG);
2090 if (!(t & (1 << instance->this_id))) {
2091 printk("scsi %d: error: invalid host id\n", instance->host_no);
2092 hostdata->aborted = 1;
2093 goto EXIT_ABORT;
2095 t ^= (1 << instance->this_id);
2096 target = 0;
2097 while (t != 1) {
2098 t >>= 1;
2099 target++;
2101 DEB_RESEL(printk("scsi %d: reselect; target: %d\n", instance->host_no, target));
2103 if (hostdata->aborted)
2104 goto EXIT_ABORT;
2106 if ((statreg & STATREG_PHASE) != PHASE_MSGIN) {
2107 printk("scsi %d: error: upon reselection interrupt not in MSGIN\n", instance->host_no);
2108 hostdata->aborted = 1;
2109 goto EXIT_ABORT;
2111 msg[0] = AM53C974_read_8(FFREG);
2112 if (!msg[0] & 0x80) {
2113 printk("scsi%d: error: expecting IDENTIFY message, got ", instance->host_no);
2114 print_msg(msg);
2115 hostdata->aborted = 1;
2116 goto EXIT_ABORT;
2118 lun = (msg[0] & 0x07);
2120 /* We need to add code for SCSI-II to track which devices have
2121 * I_T_L_Q nexuses established, and which have simple I_T_L
2122 * nexuses so we can chose to do additional data transfer. */
2123 #ifdef SCSI2
2124 #error "SCSI-II tagged queueing is not supported yet"
2125 #endif
2127 /* Find the command corresponding to the I_T_L or I_T_L_Q nexus we
2128 * just reestablished, and remove it from the disconnected queue. */
2129 for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue, prev = NULL;
2130 tmp; prev = tmp, tmp = (Scsi_Cmnd *) tmp->host_scribble)
2131 if ((target == tmp->target) && (lun == tmp->lun)
2132 #ifdef SCSI2
2133 && (tag == tmp->tag)
2134 #endif
2136 if (prev) {
2137 REMOVE(prev, (Scsi_Cmnd *) (prev->host_scribble), tmp,
2138 (Scsi_Cmnd *) (tmp->host_scribble));
2139 prev->host_scribble = tmp->host_scribble;
2140 } else {
2141 REMOVE(-1, hostdata->disconnected_queue, tmp, tmp->host_scribble);
2142 hostdata->disconnected_queue = (Scsi_Cmnd *) tmp->host_scribble;
2144 tmp->host_scribble = NULL;
2145 hostdata->connected = tmp;
2146 break;
2148 if (!tmp) {
2149 #ifdef SCSI2
2150 printk("scsi%d: warning : target %d lun %d tag %d not in disconnect_queue.\n",
2151 instance->host_no, target, lun, tag);
2152 #else
2153 printk("scsi%d: warning : target %d lun %d not in disconnect_queue.\n",
2154 instance->host_no, target, lun);
2155 #endif
2156 /* Since we have an established nexus that we can't do anything with, we must abort it. */
2157 hostdata->aborted = 1;
2158 DEB(AM53C974_keywait());
2159 goto EXIT_ABORT;
2160 } else
2161 goto EXIT_OK;
2163 EXIT_ABORT:
2164 AM53C974_write_8(CMDREG, CMDREG_SATN);
2165 AM53C974_write_8(CMDREG, CMDREG_MA);
2166 return;
2168 EXIT_OK:
2169 DEB_RESEL(printk("scsi%d: nexus established, target = %d, lun = %d, tag = %d\n",
2170 instance->host_no, target, tmp->lun, tmp->tag));
2171 AM53C974_set_sync(instance, target);
2172 AM53C974_write_8(SDIDREG, SDIREG_MASK & target); /* setup dest. id */
2173 AM53C974_write_8(CMDREG, CMDREG_MA);
2174 hostdata->dma_busy = 0;
2175 hostdata->connected->SCp.phase = PHASE_CMDOUT;
2178 /**************************************************************************
2179 * Function : AM53C974_transfer_dma(struct Scsi_Host *instance, short dir,
2180 * unsigned long length, char *data)
2182 * Purpose : setup DMA transfer
2184 * Inputs : instance -- which AM53C974
2185 * dir -- direction flag, 0: write to device, read from memory;
2186 * 1: read from device, write to memory
2187 * length -- number of bytes to transfer to from buffer
2188 * data -- pointer to data buffer
2190 * Returns : nothing
2191 **************************************************************************/
2192 static __inline__ void AM53C974_transfer_dma(struct Scsi_Host *instance, short dir,
2193 unsigned long length, char *data)
2195 AM53C974_local_declare();
2196 AM53C974_setio(instance);
2198 AM53C974_write_8(CMDREG, CMDREG_NOP);
2199 AM53C974_write_8(DMACMD, (dir << 7) | DMACMD_INTE_D); /* idle command */
2200 AM53C974_write_8(STCLREG, (unsigned char) (length & 0xff));
2201 AM53C974_write_8(STCMREG, (unsigned char) ((length & 0xff00) >> 8));
2202 AM53C974_write_8(STCHREG, (unsigned char) ((length & 0xff0000) >> 16));
2203 AM53C974_write_32(DMASTC, length & 0xffffff);
2204 AM53C974_write_32(DMASPA, virt_to_bus(data));
2205 AM53C974_write_8(CMDREG, CMDREG_IT | CMDREG_DMA);
2206 AM53C974_write_8(DMACMD, (dir << 7) | DMACMD_INTE_D | DMACMD_START);
2209 /**************************************************************************
2210 * Function : AM53C974_dma_blast(struct Scsi_Host *instance, unsigned char dmastatus,
2211 * unsigned char statreg)
2213 * Purpose : cleanup DMA transfer
2215 * Inputs : instance -- which AM53C974
2216 * dmastatus -- dma status register
2217 * statreg -- status register
2219 * Returns : nothing
2220 **************************************************************************/
2221 static void AM53C974_dma_blast(struct Scsi_Host *instance, unsigned char dmastatus,
2222 unsigned char statreg)
2224 AM53C974_local_declare();
2225 struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *) instance->hostdata;
2226 unsigned long ctcreg;
2227 int dir = statreg & STATREG_IO;
2228 int cfifo, pio, i = 0;
2229 AM53C974_setio(instance);
2231 do {
2232 cfifo = AM53C974_cfifo();
2233 i++;
2234 } while (cfifo && (i < 50000));
2235 pio = (i == 50000) ? 1 : 0;
2237 if (statreg & STATREG_CTZ) {
2238 AM53C974_write_8(DMACMD, DMACMD_IDLE);
2239 return;
2241 if (dmastatus & DMASTATUS_DONE) {
2242 AM53C974_write_8(DMACMD, DMACMD_IDLE);
2243 return;
2245 AM53C974_write_8(DMACMD, ((dir << 7) & DMACMD_DIR) | DMACMD_BLAST);
2246 while (!(AM53C974_read_8(DMASTATUS) & DMASTATUS_BCMPLT));
2247 AM53C974_write_8(DMACMD, DMACMD_IDLE);
2249 if (pio) {
2250 /* transfer residual bytes via PIO */
2251 unsigned char *wac = (unsigned char *) AM53C974_read_32(DMAWAC);
2252 printk("pio mode, residual=%d\n", AM53C974_read_8(CFIREG) & CFIREG_CF);
2253 while (AM53C974_read_8(CFIREG) & CFIREG_CF)
2254 *(wac++) = AM53C974_read_8(FFREG);
2256 ctcreg = AM53C974_read_8(CTCLREG) | (AM53C974_read_8(CTCMREG) << 8) |
2257 (AM53C974_read_8(CTCHREG) << 16);
2259 hostdata->connected->SCp.ptr += hostdata->connected->SCp.this_residual - ctcreg;
2260 hostdata->connected->SCp.this_residual = ctcreg;
2263 /**************************************************************************
2264 * Function : AM53C974_intr_bus_reset(struct Scsi_Host *instance)
2266 * Purpose : handle bus reset interrupt
2268 * Inputs : instance -- which AM53C974
2270 * Returns : nothing
2271 **************************************************************************/
2272 static void AM53C974_intr_bus_reset(struct Scsi_Host *instance)
2274 AM53C974_local_declare();
2275 unsigned char cntlreg1;
2276 AM53C974_setio(instance);
2278 AM53C974_write_8(CMDREG, CMDREG_CFIFO);
2279 AM53C974_write_8(CMDREG, CMDREG_NOP);
2281 cntlreg1 = AM53C974_read_8(CNTLREG1);
2282 AM53C974_write_8(CNTLREG1, cntlreg1 | CNTLREG1_DISR);
2285 /**************************************************************************
2286 * Function : int AM53C974_abort(Scsi_Cmnd *cmd)
2288 * Purpose : abort a command
2290 * Inputs : cmd - the Scsi_Cmnd to abort, code - code to set the
2291 * host byte of the result field to, if zero DID_ABORTED is
2292 * used.
2294 * Returns : 0 - success, -1 on failure.
2295 **************************************************************************/
2296 int AM53C974_abort(Scsi_Cmnd * cmd)
2298 AM53C974_local_declare();
2299 unsigned long flags;
2300 struct Scsi_Host *instance = cmd->host;
2301 struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *) instance->hostdata;
2302 Scsi_Cmnd *tmp, **prev;
2304 #ifdef AM53C974_DEBUG
2305 deb_stop = 1;
2306 #endif
2307 save_flags(flags);
2308 cli();
2309 AM53C974_setio(instance);
2311 DEB_ABORT(printk(SEPARATOR_LINE));
2312 DEB_ABORT(printk("scsi%d : AM53C974_abort called -- trouble starts!!\n", instance->host_no));
2313 DEB_ABORT(AM53C974_print(instance));
2314 DEB_ABORT(AM53C974_keywait());
2316 /* Case 1 : If the command is the currently executing command,
2317 we'll set the aborted flag and return control so that the
2318 information transfer routine can exit cleanly. */
2319 if ((hostdata->connected == cmd) || (hostdata->sel_cmd == cmd)) {
2320 DEB_ABORT(printk("scsi%d: aborting connected command\n", instance->host_no));
2321 hostdata->aborted = 1;
2322 hostdata->msgout[0] = ABORT;
2323 restore_flags(flags);
2324 return (SCSI_ABORT_PENDING);
2326 /* Case 2 : If the command hasn't been issued yet,
2327 we simply remove it from the issue queue. */
2328 for (prev = (Scsi_Cmnd **) & (hostdata->issue_queue),
2329 tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp;
2330 prev = (Scsi_Cmnd **) & (tmp->host_scribble),
2331 tmp = (Scsi_Cmnd *) tmp->host_scribble) {
2332 if (cmd == tmp) {
2333 DEB_ABORT(printk("scsi%d : abort removed command from issue queue.\n", instance->host_no));
2334 REMOVE(5, *prev, tmp, tmp->host_scribble);
2335 (*prev) = (Scsi_Cmnd *) tmp->host_scribble;
2336 tmp->host_scribble = NULL;
2337 tmp->result = DID_ABORT << 16;
2338 restore_flags(flags);
2339 tmp->done(tmp);
2340 return (SCSI_ABORT_SUCCESS);
2342 #ifdef AM53C974_DEBUG_ABORT
2343 else {
2344 if (prev == (Scsi_Cmnd **) tmp)
2345 printk("scsi%d : LOOP\n", instance->host_no);
2347 #endif
2350 /* Case 3 : If any commands are connected, we're going to fail the abort
2351 * and let the high level SCSI driver retry at a later time or
2352 * issue a reset.
2354 * Timeouts, and therefore aborted commands, will be highly unlikely
2355 * and handling them cleanly in this situation would make the common
2356 * case of noresets less efficient, and would pollute our code. So,
2357 * we fail. */
2358 if (hostdata->connected || hostdata->sel_cmd) {
2359 DEB_ABORT(printk("scsi%d : abort failed, other command connected.\n", instance->host_no));
2360 restore_flags(flags);
2361 return (SCSI_ABORT_NOT_RUNNING);
2363 /* Case 4: If the command is currently disconnected from the bus, and
2364 * there are no connected commands, we reconnect the I_T_L or
2365 * I_T_L_Q nexus associated with it, go into message out, and send
2366 * an abort message. */
2367 for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue; tmp;
2368 tmp = (Scsi_Cmnd *) tmp->host_scribble) {
2369 if (cmd == tmp) {
2370 DEB_ABORT(printk("scsi%d: aborting disconnected command\n", instance->host_no));
2371 hostdata->aborted = 1;
2372 hostdata->msgout[0] = ABORT;
2373 hostdata->selecting = 1;
2374 hostdata->sel_cmd = tmp;
2375 AM53C974_write_8(CMDREG, CMDREG_DSR);
2376 restore_flags(flags);
2377 return (SCSI_ABORT_PENDING);
2381 /* Case 5 : If we reached this point, the command was not found in any of
2382 * the queues.
2384 * We probably reached this point because of an unlikely race condition
2385 * between the command completing successfully and the abortion code,
2386 * so we won't panic, but we will notify the user in case something really
2387 * broke. */
2388 DEB_ABORT(printk("scsi%d : abort failed, command not found.\n", instance->host_no));
2389 restore_flags(flags);
2390 return (SCSI_ABORT_NOT_RUNNING);
2393 /**************************************************************************
2394 * Function : int AM53C974_reset(Scsi_Cmnd *cmd)
2396 * Purpose : reset the SCSI controller and bus
2398 * Inputs : cmd -- which command within the command block was responsible for the reset
2400 * Returns : status (SCSI_ABORT_SUCCESS)
2402 * FIXME(eric) the reset_flags are ignored.
2403 **************************************************************************/
2404 int AM53C974_reset(Scsi_Cmnd * cmd, unsigned int reset_flags)
2406 AM53C974_local_declare();
2407 unsigned long flags;
2408 int i;
2409 struct Scsi_Host *instance = cmd->host;
2410 struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *) instance->hostdata;
2411 AM53C974_setio(instance);
2413 save_flags(flags);
2414 cli();
2415 DEB(printk("AM53C974_reset called; "));
2417 printk("AM53C974_reset called\n");
2418 AM53C974_print(instance);
2419 AM53C974_keywait();
2421 /* do hard reset */
2422 AM53C974_write_8(CMDREG, CMDREG_RDEV);
2423 AM53C974_write_8(CMDREG, CMDREG_NOP);
2424 hostdata->msgout[0] = NOP;
2425 for (i = 0; i < 8; i++) {
2426 hostdata->busy[i] = 0;
2427 hostdata->sync_per[i] = DEF_STP;
2428 hostdata->sync_off[i] = 0;
2429 hostdata->sync_neg[i] = 0;
2431 hostdata->last_message[0] = NOP;
2432 hostdata->sel_cmd = NULL;
2433 hostdata->connected = NULL;
2434 hostdata->issue_queue = NULL;
2435 hostdata->disconnected_queue = NULL;
2436 hostdata->in_reset = 0;
2437 hostdata->aborted = 0;
2438 hostdata->selecting = 0;
2439 hostdata->disconnecting = 0;
2440 hostdata->dma_busy = 0;
2442 /* reset bus */
2443 AM53C974_write_8(CNTLREG1, CNTLREG1_DISR | instance->this_id); /* disable interrupt upon SCSI RESET */
2444 AM53C974_write_8(CMDREG, CMDREG_RBUS); /* reset SCSI bus */
2445 udelay(40);
2446 AM53C974_config_after_reset(instance);
2448 restore_flags(flags);
2449 cmd->result = DID_RESET << 16;
2450 cmd->scsi_done(cmd);
2451 return SCSI_ABORT_SUCCESS;
2456 * AM53C974_release()
2458 * Release resources allocated for a single AM53C974 adapter.
2460 int AM53C974_release(struct Scsi_Host *shp)
2462 free_irq(shp->irq, shp);
2463 scsi_unregister(shp);
2464 return 0;
2468 #ifdef MODULE
2469 static Scsi_Host_Template driver_template = AM53C974;
2471 /* You can specify overrides=a,b,c,d in the same format at AM53C974=a,b,c,d
2472 on boot up */
2474 MODULE_PARM(overrides, "1-32i");
2475 #include "scsi_module.c"
2476 #endif