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