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