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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [scsi/] [AM53C974.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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