OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [scsi/] [AM53C974.c] - Blame information for rev 1275

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.