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

Subversion Repositories or1k

[/] [or1k/] [tags/] [before_ORP/] [uclinux/] [uClinux-2.0.x/] [drivers/] [scsi/] [AM53C974.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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