File: /usr/src/linux/drivers/scsi/NCR5380.h

1     /* 
2      * NCR 5380 defines
3      *
4      * Copyright 1993, Drew Eckhardt
5      *	Visionary Computing
6      *	(Unix consulting and custom programming)
7      * 	drew@colorado.edu
8      *      +1 (303) 666-5836
9      *
10      * DISTRIBUTION RELEASE 7
11      *
12      * For more information, please consult 
13      *
14      * NCR 5380 Family
15      * SCSI Protocol Controller
16      * Databook
17      * NCR Microelectronics
18      * 1635 Aeroplaza Drive
19      * Colorado Springs, CO 80916
20      * 1+ (719) 578-3400
21      * 1+ (800) 334-5454
22      */
23     
24     /*
25      * $Log: NCR5380.h,v $
26      */
27     
28     #ifndef NCR5380_H
29     #define NCR5380_H
30     
31     #define NCR5380_PUBLIC_RELEASE 7
32     #define NCR53C400_PUBLIC_RELEASE 2
33     
34     #define NDEBUG_ARBITRATION	0x1
35     #define NDEBUG_AUTOSENSE	0x2
36     #define NDEBUG_DMA		0x4
37     #define NDEBUG_HANDSHAKE	0x8
38     #define NDEBUG_INFORMATION	0x10
39     #define NDEBUG_INIT		0x20
40     #define NDEBUG_INTR		0x40
41     #define NDEBUG_LINKED		0x80
42     #define NDEBUG_MAIN		0x100
43     #define NDEBUG_NO_DATAOUT	0x200
44     #define NDEBUG_NO_WRITE		0x400
45     #define NDEBUG_PIO		0x800
46     #define NDEBUG_PSEUDO_DMA	0x1000
47     #define NDEBUG_QUEUES		0x2000
48     #define NDEBUG_RESELECTION	0x4000
49     #define NDEBUG_SELECTION	0x8000
50     #define NDEBUG_USLEEP		0x10000
51     #define NDEBUG_LAST_BYTE_SENT	0x20000
52     #define NDEBUG_RESTART_SELECT	0x40000
53     #define NDEBUG_EXTENDED		0x80000
54     #define NDEBUG_C400_PREAD	0x100000
55     #define NDEBUG_C400_PWRITE	0x200000
56     #define NDEBUG_LISTS		0x400000
57     
58     /* 
59      * The contents of the OUTPUT DATA register are asserted on the bus when
60      * either arbitration is occurring or the phase-indicating signals (
61      * IO, CD, MSG) in the TARGET COMMAND register and the ASSERT DATA
62      * bit in the INITIATOR COMMAND register is set.
63      */
64     
65     #define OUTPUT_DATA_REG         0       /* wo DATA lines on SCSI bus */
66     #define CURRENT_SCSI_DATA_REG   0       /* ro same */
67     
68     #define INITIATOR_COMMAND_REG	1	/* rw */
69     #define ICR_ASSERT_RST		0x80	/* rw Set to assert RST  */
70     #define ICR_ARBITRATION_PROGRESS 0x40	/* ro Indicates arbitration complete */
71     #define ICR_TRI_STATE		0x40	/* wo Set to tri-state drivers */
72     #define ICR_ARBITRATION_LOST	0x20	/* ro Indicates arbitration lost */
73     #define ICR_DIFF_ENABLE		0x20	/* wo Set to enable diff. drivers */
74     #define ICR_ASSERT_ACK		0x10	/* rw ini Set to assert ACK */
75     #define ICR_ASSERT_BSY		0x08	/* rw Set to assert BSY */
76     #define ICR_ASSERT_SEL 		0x04	/* rw Set to assert SEL */
77     #define ICR_ASSERT_ATN		0x02	/* rw Set to assert ATN */
78     #define ICR_ASSERT_DATA		0x01	/* rw SCSI_DATA_REG is asserted */
79     
80     #ifdef DIFFERENTIAL
81     #define ICR_BASE		ICR_DIFF_ENABLE
82     #else
83     #define ICR_BASE		0
84     #endif
85     
86     #define MODE_REG		2
87     /*
88      * Note : BLOCK_DMA code will keep DRQ asserted for the duration of the 
89      * transfer, causing the chip to hog the bus.  You probably don't want 
90      * this.
91      */
92     #define MR_BLOCK_DMA_MODE	0x80	/* rw block mode DMA */
93     #define MR_TARGET		0x40	/* rw target mode */
94     #define MR_ENABLE_PAR_CHECK   0x20	/* rw enable parity checking */
95     #define MR_ENABLE_PAR_INTR	0x10	/* rw enable bad parity interrupt */
96     #define MR_ENABLE_EOP_INTR	0x08	/* rw enable eop interrupt */
97     #define MR_MONITOR_BSY	0x04	/* rw enable int on unexpected bsy fail */
98     #define MR_DMA_MODE		0x02	/* rw DMA / pseudo DMA mode */
99     #define MR_ARBITRATE		0x01	/* rw start arbitration */
100     
101     #ifdef PARITY
102     #define MR_BASE			MR_ENABLE_PAR_CHECK
103     #else
104     #define MR_BASE			0
105     #endif
106     
107     #define TARGET_COMMAND_REG	3
108     #define TCR_LAST_BYTE_SENT	0x80	/* ro DMA done */
109     #define TCR_ASSERT_REQ		0x08	/* tgt rw assert REQ */
110     #define TCR_ASSERT_MSG		0x04	/* tgt rw assert MSG */
111     #define TCR_ASSERT_CD		0x02	/* tgt rw assert CD */
112     #define TCR_ASSERT_IO		0x01	/* tgt rw assert IO */
113     
114     #define STATUS_REG		4	/* ro */
115     /*
116      * Note : a set bit indicates an active signal, driven by us or another 
117      * device.
118      */
119     #define SR_RST			0x80	
120     #define SR_BSY			0x40
121     #define SR_REQ			0x20
122     #define SR_MSG			0x10
123     #define SR_CD			0x08
124     #define SR_IO			0x04
125     #define SR_SEL			0x02
126     #define SR_DBP			0x01
127     
128     /*
129      * Setting a bit in this register will cause an interrupt to be generated when 
130      * BSY is false and SEL true and this bit is asserted  on the bus.
131      */
132     #define SELECT_ENABLE_REG	4	/* wo */
133     
134     #define BUS_AND_STATUS_REG	5	/* ro */
135     #define BASR_END_DMA_TRANSFER	0x80	/* ro set on end of transfer */
136     #define BASR_DRQ		0x40	/* ro mirror of DRQ pin */
137     #define BASR_PARITY_ERROR	0x20	/* ro parity error detected */
138     #define BASR_IRQ		0x10	/* ro mirror of IRQ pin */
139     #define BASR_PHASE_MATCH	0x08	/* ro Set when MSG CD IO match TCR */
140     #define BASR_BUSY_ERROR		0x04	/* ro Unexpected change to inactive state */
141     #define BASR_ATN 		0x02	/* ro BUS status */
142     #define BASR_ACK		0x01	/* ro BUS status */
143     
144     /* Write any value to this register to start a DMA send */
145     #define START_DMA_SEND_REG	5	/* wo */
146     
147     /* 
148      * Used in DMA transfer mode, data is latched from the SCSI bus on
149      * the falling edge of REQ (ini) or ACK (tgt)
150      */
151     #define INPUT_DATA_REG			6	/* ro */
152     
153     /* Write any value to this register to start a DMA receive */
154     #define START_DMA_TARGET_RECEIVE_REG	6	/* wo */
155     
156     /* Read this register to clear interrupt conditions */
157     #define RESET_PARITY_INTERRUPT_REG	7	/* ro */
158     
159     /* Write any value to this register to start an ini mode DMA receive */
160     #define START_DMA_INITIATOR_RECEIVE_REG 7	/* wo */
161     
162     #define C400_CONTROL_STATUS_REG NCR53C400_register_offset-8      /* rw */
163     
164     #define CSR_RESET              0x80    /* wo  Resets 53c400 */
165     #define CSR_53C80_REG          0x80    /* ro  5380 registers busy */
166     #define CSR_TRANS_DIR          0x40    /* rw  Data transfer direction */
167     #define CSR_SCSI_BUFF_INTR     0x20    /* rw  Enable int on transfer ready */
168     #define CSR_53C80_INTR         0x10    /* rw  Enable 53c80 interrupts */
169     #define CSR_SHARED_INTR        0x08    /* rw  Interrupt sharing */
170     #define CSR_HOST_BUF_NOT_RDY   0x04    /* ro  Is Host buffer ready */
171     #define CSR_SCSI_BUF_RDY       0x02    /* ro  SCSI buffer read */
172     #define CSR_GATED_53C80_IRQ    0x01    /* ro  Last block xferred */
173     
174     #if 0
175     #define CSR_BASE CSR_SCSI_BUFF_INTR | CSR_53C80_INTR
176     #else
177     #define CSR_BASE CSR_53C80_INTR
178     #endif
179     
180     /* Number of 128-byte blocks to be transferred */
181     #define C400_BLOCK_COUNTER_REG   NCR53C400_register_offset-7      /* rw */
182     
183     /* Resume transfer after disconnect */
184     #define C400_RESUME_TRANSFER_REG NCR53C400_register_offset-6      /* wo */
185     
186     /* Access to host buffer stack */
187     #define C400_HOST_BUFFER         NCR53C400_register_offset-4      /* rw */
188     
189     
190     /* Note : PHASE_* macros are based on the values of the STATUS register */
191     #define PHASE_MASK 	(SR_MSG | SR_CD | SR_IO)
192     
193     #define PHASE_DATAOUT		0
194     #define PHASE_DATAIN		SR_IO
195     #define PHASE_CMDOUT		SR_CD
196     #define PHASE_STATIN		(SR_CD | SR_IO)
197     #define PHASE_MSGOUT		(SR_MSG | SR_CD)
198     #define PHASE_MSGIN		(SR_MSG | SR_CD | SR_IO)
199     #define PHASE_UNKNOWN		0xff
200     
201     /* 
202      * Convert status register phase to something we can use to set phase in 
203      * the target register so we can get phase mismatch interrupts on DMA 
204      * transfers.
205      */
206      
207     #define PHASE_SR_TO_TCR(phase) ((phase) >> 2)	
208     
209     /*
210      * The internal should_disconnect() function returns these based on the 
211      * expected length of a disconnect if a device supports disconnect/
212      * reconnect.
213      */
214     
215     #define DISCONNECT_NONE		0
216     #define DISCONNECT_TIME_TO_DATA	1
217     #define DISCONNECT_LONG		2
218     
219     /* 
220      * These are "special" values for the tag parameter passed to NCR5380_select.
221      */
222     
223     #define TAG_NEXT	-1 	/* Use next free tag */
224     #define TAG_NONE	-2	/* 
225     				 * Establish I_T_L nexus instead of I_T_L_Q
226     				 * even on SCSI-II devices.
227     				 */
228     
229     /*
230      * These are "special" values for the irq and dma_channel fields of the 
231      * Scsi_Host structure
232      */
233     
234     #define IRQ_NONE	255
235     #define DMA_NONE	255
236     #define IRQ_AUTO	254
237     #define DMA_AUTO	254
238     #define PORT_AUTO	0xffff		/* autoprobe io port for 53c400a */
239     
240     #define FLAG_HAS_LAST_BYTE_SENT		1	/* NCR53c81 or better */
241     #define FLAG_CHECK_LAST_BYTE_SENT	2	/* Only test once */
242     #define FLAG_NCR53C400			4	/* NCR53c400 */
243     #define FLAG_NO_PSEUDO_DMA		8	/* Inhibit DMA */
244     #define FLAG_DTC3181E			16	/* DTC3181E */
245     
246     #ifndef ASM
247     struct NCR5380_hostdata {
248         NCR5380_implementation_fields;		/* implementation specific */
249         unsigned char id_mask, id_higher_mask;	/* 1 << id, all bits greater */
250         unsigned char targets_present;		/* targets we have connected
251     						   to, so we can call a select
252     						   failure a retryable condition */
253         volatile unsigned char busy[8];		/* index = target, bit = lun */
254     #if defined(REAL_DMA) || defined(REAL_DMA_POLL)
255         volatile int dma_len;			/* requested length of DMA */
256     #endif
257         volatile unsigned char last_message;	/* last message OUT */
258         volatile Scsi_Cmnd *connected;		/* currently connected command */
259         volatile Scsi_Cmnd *issue_queue;		/* waiting to be issued */
260         volatile Scsi_Cmnd *disconnected_queue;	/* waiting for reconnect */
261         volatile int restart_select;		/* we have disconnected,
262     						   used to restart 
263     						   NCR5380_select() */
264         volatile unsigned aborted:1;		/* flag, says aborted */
265         int flags;
266     #ifdef USLEEP
267         unsigned long time_expires;			/* in jiffies, set prior to sleeping */
268         struct Scsi_Host *next_timer;
269         int select_time;				/* timer in select for target response */
270         volatile Scsi_Cmnd *selecting;
271     #endif
272     #ifdef NCR5380_STATS
273         unsigned timebase;				/* Base for time calcs */
274         long time_read[8];				/* time to do reads */
275         long time_write[8];				/* time to do writes */
276         unsigned long bytes_read[8];		/* bytes read */
277         unsigned long bytes_write[8];		/* bytes written */
278         unsigned pendingr;
279         unsigned pendingw;
280     #endif
281     };
282     
283     #ifdef __KERNEL__
284     static struct Scsi_Host *first_instance;		/* linked list of 5380's */
285     
286     #if defined(AUTOPROBE_IRQ)
287     static int NCR5380_probe_irq (struct Scsi_Host *instance, int possible);
288     #endif
289     static void NCR5380_init (struct Scsi_Host *instance, int flags);
290     static void NCR5380_information_transfer (struct Scsi_Host *instance);
291     #ifndef DONT_USE_INTR
292     static void NCR5380_intr (int irq, void *dev_id, struct pt_regs * regs);
293     static void do_NCR5380_intr (int irq, void *dev_id, struct pt_regs * regs);
294     #endif
295     static void NCR5380_main (void);
296     static void NCR5380_print_options (struct Scsi_Host *instance);
297     static void NCR5380_print_phase (struct Scsi_Host *instance);
298     static void NCR5380_print (struct Scsi_Host *instance);
299     #ifndef NCR5380_abort
300     static
301     #endif
302     int NCR5380_abort (Scsi_Cmnd *cmd);
303     #ifndef NCR5380_reset
304     static
305     #endif
306     int NCR5380_reset (Scsi_Cmnd *cmd, unsigned int reset_flags);
307     #ifndef NCR5380_queue_command
308     static 
309     #endif
310     int NCR5380_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *));
311     
312     
313     static void NCR5380_reselect (struct Scsi_Host *instance);
314     static int NCR5380_select (struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag);
315     #if defined(PSEUDO_DMA) || defined(REAL_DMA) || defined(REAL_DMA_POLL)
316     static int NCR5380_transfer_dma (struct Scsi_Host *instance,
317     	unsigned char *phase, int *count, unsigned char **data);
318     #endif
319     static int NCR5380_transfer_pio (struct Scsi_Host *instance,
320     	unsigned char *phase, int *count, unsigned char **data);
321     
322     #if (defined(REAL_DMA) || defined(REAL_DMA_POLL))
323     
324     #if defined(i386) || defined(__alpha__)
325     
326     static __inline__ int NCR5380_pc_dma_setup (struct Scsi_Host *instance,
327     	unsigned char *ptr, unsigned int count, unsigned char mode) {
328         unsigned limit;
329         unsigned long bus_addr = virt_to_bus(ptr);
330     
331         if (instance->dma_channel <=3) {
332     	if (count > 65536)
333     	    count = 65536;
334     	limit = 65536 - (bus_addr & 0xFFFF);
335         } else {
336     	if (count > 65536 * 2) 
337     	    count = 65536 * 2;
338     	limit = 65536* 2 - (bus_addr & 0x1FFFF);
339         }
340     
341         if (count > limit) count = limit;
342     
343         if ((count & 1) || (bus_addr & 1))
344     	panic ("scsi%d : attempted unaligned DMA transfer\n", instance->host_no);
345         cli();
346         disable_dma(instance->dma_channel);
347         clear_dma_ff(instance->dma_channel);
348         set_dma_addr(instance->dma_channel, bus_addr);
349         set_dma_count(instance->dma_channel, count);
350         set_dma_mode(instance->dma_channel, mode);
351         enable_dma(instance->dma_channel);
352         sti();
353         return count;
354     }
355     
356     static __inline__ int NCR5380_pc_dma_write_setup (struct Scsi_Host *instance,
357         unsigned char *src, unsigned int count) {
358         return NCR5380_pc_dma_setup (instance, src, count, DMA_MODE_WRITE);
359     }
360     
361     static __inline__ int NCR5380_pc_dma_read_setup (struct Scsi_Host *instance,
362         unsigned char *src, unsigned int count) {
363         return NCR5380_pc_dma_setup (instance, src, count, DMA_MODE_READ);
364     }
365     
366     static __inline__ int NCR5380_pc_dma_residual (struct Scsi_Host *instance) {
367         register int tmp;
368         cli();
369         clear_dma_ff(instance->dma_channel);
370         tmp = get_dma_residue(instance->dma_channel);
371         sti();
372         return tmp;
373     }
374     #endif /* defined(i386) || defined(__alpha__) */
375     #endif /* defined(REAL_DMA)  */
376     #endif /* __KERNEL__ */
377     #endif /* ndef ASM */
378     #endif /* NCR5380_H */
379