Bug Summary

File:obj-scan-build/../linux/src/drivers/scsi/AM53C974.c
Location:line 1520, column 61
Description:Value stored to 'cfifo' is never read

Annotated Source Code

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