1 /*=======================================================/
2   Header file for nsp_cs.c
3       By: YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>
4 
5     Ver.1.0 : Cut unused lines.
6     Ver 0.1 : Initial version.
7 
8     This software may be used and distributed according to the terms of
9     the GNU General Public License.
10 
11 =========================================================*/
12 
13 /* $Id: nsp_cs.h,v 1.20 2003/09/24 10:38:18 elca Exp $ */
14 
15 #ifndef  __nsp_cs__
16 #define  __nsp_cs__
17 
18 /* for debugging */
19 //#define NSP_DEBUG 9
20 
21 /*
22 #define static
23 #define inline
24 */
25 
26 /************************************
27  * Some useful macros...
28  */
29 #define NUMBER(arr) ((int) (sizeof(arr) / sizeof(arr[0]))) /* from XtNumber() in /usr/X11R6/include/X11/Intrinsic.h */
30 #define BIT(x)      (1L << (x))
31 #define MIN(a,b)    ((a) > (b) ? (b) : (a))
32 
33 /* SCSI initiator must be ID 7 */
34 #define NSP_INITIATOR_ID  7
35 
36 #define NSP_SELTIMEOUT 200
37 
38 /***************************************************************************
39  * register definitions
40  ***************************************************************************/
41 /*========================================================================
42  * base register
43  ========================================================================*/
44 #define	IRQCONTROL	0x00  /* R */
45 #  define IRQCONTROL_RESELECT_CLEAR     BIT(0)
46 #  define IRQCONTROL_PHASE_CHANGE_CLEAR BIT(1)
47 #  define IRQCONTROL_TIMER_CLEAR        BIT(2)
48 #  define IRQCONTROL_FIFO_CLEAR         BIT(3)
49 #  define IRQCONTROL_SCSI_IRQ_MASK      BIT(4)
50 #  define IRQCONTROL_EXT_IRQ_MASK       BIT(5)
51 #  define IRQCONTROL_TIMER_IRQ_MASK     BIT(6)
52 #  define IRQCONTROL_FIFO_IRQ_MASK      BIT(7)
53 #  define IRQCONTROL_ALL_MASK           (IRQCONTROL_SCSI_IRQ_MASK  | \
54                                          IRQCONTROL_EXT_IRQ_MASK   | \
55                                          IRQCONTROL_TIMER_IRQ_MASK | \
56                                          IRQCONTROL_FIFO_IRQ_MASK  )
57 #  define IRQCONTROL_ALL_CLEAR          (IRQCONTROL_RESELECT_CLEAR     | \
58 					 IRQCONTROL_PHASE_CHANGE_CLEAR | \
59 					 IRQCONTROL_TIMER_CLEAR        | \
60 					 IRQCONTROL_FIFO_CLEAR         )
61 #  define IRQCONTROL_ALL_CLEAR_AND_MASK  (IRQCONTROL_ALL_MASK | \
62                                           IRQCONTROL_ALL_CLEAR)
63 
64 #define	IRQSTATUS	0x00  /* W */
65 #  define IRQSTATUS_SCSI  BIT(0)
66 #  define IRQSTATUS_TIMER BIT(2)
67 #  define IRQSTATUS_FIFO  BIT(3)
68 #  define IRQSTATUS_MASK  0x0f
69 
70 #define	IFSELECT	0x01 /* W */
71 #  define IF_IFSEL    BIT(0)
72 #  define IF_REGSEL   BIT(2)
73 
74 #define	FIFOSTATUS	0x01 /* R */
75 #  define FIFOSTATUS_CHIP_REVISION_MASK 0x0f
76 #  define FIFOSTATUS_CHIP_ID_MASK       0x70
77 #  define FIFOSTATUS_FULL_EMPTY         BIT(7)
78 
79 #define	INDEXREG	0x02 /* R/W */
80 #define	DATAREG		0x03 /* R/W */
81 #define	FIFODATA	0x04 /* R/W */
82 #define	FIFODATA1	0x05 /* R/W */
83 #define	FIFODATA2	0x06 /* R/W */
84 #define	FIFODATA3	0x07 /* R/W */
85 
86 /*====================================================================
87  * indexed register
88  ====================================================================*/
89 #define EXTBUSCTRL	0x10 /* R/W,deleted */
90 
91 #define CLOCKDIV	0x11 /* R/W */
92 #  define CLOCK_40M 0x02
93 #  define CLOCK_20M 0x01
94 #  define FAST_20   BIT(2)
95 
96 #define TERMPWRCTRL	0x13 /* R/W */
97 #  define POWER_ON BIT(0)
98 
99 #define SCSIIRQMODE	0x15 /* R/W */
100 #  define SCSI_PHASE_CHANGE_EI BIT(0)
101 #  define RESELECT_EI          BIT(4)
102 #  define FIFO_IRQ_EI          BIT(5)
103 #  define SCSI_RESET_IRQ_EI    BIT(6)
104 
105 #define IRQPHASESENCE	0x16 /* R */
106 #  define LATCHED_MSG      BIT(0)
107 #  define LATCHED_IO       BIT(1)
108 #  define LATCHED_CD       BIT(2)
109 #  define LATCHED_BUS_FREE BIT(3)
110 #  define PHASE_CHANGE_IRQ BIT(4)
111 #  define RESELECT_IRQ     BIT(5)
112 #  define FIFO_IRQ         BIT(6)
113 #  define SCSI_RESET_IRQ   BIT(7)
114 
115 #define TIMERCOUNT	0x17 /* R/W */
116 
117 #define SCSIBUSCTRL	0x18 /* R/W */
118 #  define SCSI_SEL         BIT(0)
119 #  define SCSI_RST         BIT(1)
120 #  define SCSI_DATAOUT_ENB BIT(2)
121 #  define SCSI_ATN         BIT(3)
122 #  define SCSI_ACK         BIT(4)
123 #  define SCSI_BSY         BIT(5)
124 #  define AUTODIRECTION    BIT(6)
125 #  define ACKENB           BIT(7)
126 
127 #define SCSIBUSMON	0x19 /* R */
128 
129 #define SETARBIT	0x1A /* W */
130 #  define ARBIT_GO         BIT(0)
131 #  define ARBIT_FLAG_CLEAR BIT(1)
132 
133 #define ARBITSTATUS	0x1A /* R */
134 /*#  define ARBIT_GO        BIT(0)*/
135 #  define ARBIT_WIN        BIT(1)
136 #  define ARBIT_FAIL       BIT(2)
137 #  define RESELECT_FLAG    BIT(3)
138 
139 #define PARITYCTRL	0x1B  /* W */
140 #define PARITYSTATUS	0x1B  /* R */
141 
142 #define COMMANDCTRL	0x1C  /* W */
143 #  define CLEAR_COMMAND_POINTER BIT(0)
144 #  define AUTO_COMMAND_GO       BIT(1)
145 
146 #define RESELECTID	0x1C  /* R   */
147 #define COMMANDDATA	0x1D  /* R/W */
148 
149 #define POINTERCLR	0x1E  /*   W */
150 #  define POINTER_CLEAR      BIT(0)
151 #  define ACK_COUNTER_CLEAR  BIT(1)
152 #  define REQ_COUNTER_CLEAR  BIT(2)
153 #  define HOST_COUNTER_CLEAR BIT(3)
154 #  define READ_SOURCE        (BIT(4) | BIT(5))
155 #    define ACK_COUNTER        (0)
156 #    define REQ_COUNTER        (BIT(4))
157 #    define HOST_COUNTER       (BIT(5))
158 
159 #define TRANSFERCOUNT	0x1E  /* R   */
160 
161 #define TRANSFERMODE	0x20  /* R/W */
162 #  define MODE_MEM8   BIT(0)
163 #  define MODE_MEM32  BIT(1)
164 #  define MODE_ADR24  BIT(2)
165 #  define MODE_ADR32  BIT(3)
166 #  define MODE_IO8    BIT(4)
167 #  define MODE_IO32   BIT(5)
168 #  define TRANSFER_GO BIT(6)
169 #  define BRAIND      BIT(7)
170 
171 #define SYNCREG		0x21 /* R/W */
172 #  define SYNCREG_OFFSET_MASK  0x0f
173 #  define SYNCREG_PERIOD_MASK  0xf0
174 #  define SYNCREG_PERIOD_SHIFT 4
175 
176 #define SCSIDATALATCH	0x22 /*   W */
177 #define SCSIDATAIN	0x22 /* R   */
178 #define SCSIDATAWITHACK	0x23 /* R/W */
179 #define SCAMCONTROL	0x24 /*   W */
180 #define SCAMSTATUS	0x24 /* R   */
181 #define SCAMDATA	0x25 /* R/W */
182 
183 #define OTHERCONTROL	0x26 /* R/W */
184 #  define TPL_ROM_WRITE_EN BIT(0)
185 #  define TPWR_OUT         BIT(1)
186 #  define TPWR_SENSE       BIT(2)
187 #  define RA8_CONTROL      BIT(3)
188 
189 #define ACKWIDTH	0x27 /* R/W */
190 #define CLRTESTPNT	0x28 /*   W */
191 #define ACKCNTLD	0x29 /*   W */
192 #define REQCNTLD	0x2A /*   W */
193 #define HSTCNTLD	0x2B /*   W */
194 #define CHECKSUM	0x2C /* R/W */
195 
196 /************************************************************************
197  * Input status bit definitions.
198  ************************************************************************/
199 #define S_MESSAGE	BIT(0)    /* Message line from SCSI bus      */
200 #define S_IO		BIT(1)    /* Input/Output line from SCSI bus */
201 #define S_CD		BIT(2)    /* Command/Data line from SCSI bus */
202 #define S_BUSY		BIT(3)    /* Busy line from SCSI bus         */
203 #define S_ACK		BIT(4)    /* Acknowlege line from SCSI bus   */
204 #define S_REQUEST	BIT(5)    /* Request line from SCSI bus      */
205 #define S_SELECT	BIT(6)	  /*                                 */
206 #define S_ATN		BIT(7)	  /*                                 */
207 
208 /***********************************************************************
209  * Useful Bus Monitor status combinations.
210  ***********************************************************************/
211 #define BUSMON_SEL         S_SELECT
212 #define BUSMON_BSY         S_BUSY
213 #define BUSMON_REQ         S_REQUEST
214 #define BUSMON_IO          S_IO
215 #define BUSMON_ACK         S_ACK
216 #define BUSMON_BUS_FREE    0
217 #define BUSMON_COMMAND     ( S_BUSY | S_CD |                    S_REQUEST )
218 #define BUSMON_MESSAGE_IN  ( S_BUSY | S_CD | S_IO | S_MESSAGE | S_REQUEST )
219 #define BUSMON_MESSAGE_OUT ( S_BUSY | S_CD |        S_MESSAGE | S_REQUEST )
220 #define BUSMON_DATA_IN     ( S_BUSY |        S_IO |             S_REQUEST )
221 #define BUSMON_DATA_OUT    ( S_BUSY |                           S_REQUEST )
222 #define BUSMON_STATUS      ( S_BUSY | S_CD | S_IO |             S_REQUEST )
223 #define BUSMON_SELECT      (                 S_IO |                        S_SELECT )
224 #define BUSMON_RESELECT    (                 S_IO |                        S_SELECT )
225 #define BUSMON_PHASE_MASK  (          S_CD | S_IO | S_MESSAGE |            S_SELECT )
226 
227 #define BUSPHASE_SELECT      ( BUSMON_SELECT      & BUSMON_PHASE_MASK )
228 #define BUSPHASE_COMMAND     ( BUSMON_COMMAND     & BUSMON_PHASE_MASK )
229 #define BUSPHASE_MESSAGE_IN  ( BUSMON_MESSAGE_IN  & BUSMON_PHASE_MASK )
230 #define BUSPHASE_MESSAGE_OUT ( BUSMON_MESSAGE_OUT & BUSMON_PHASE_MASK )
231 #define BUSPHASE_DATA_IN     ( BUSMON_DATA_IN     & BUSMON_PHASE_MASK )
232 #define BUSPHASE_DATA_OUT    ( BUSMON_DATA_OUT    & BUSMON_PHASE_MASK )
233 #define BUSPHASE_STATUS      ( BUSMON_STATUS      & BUSMON_PHASE_MASK )
234 
235 /*====================================================================*/
236 
237 typedef struct scsi_info_t {
238 	dev_link_t             link;
239 	struct Scsi_Host      *host;
240 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74))
241 	dev_node_t             node;
242 #else
243 	int	               ndev;
244 	dev_node_t             node[8];
245 	struct bus_operations *bus;
246 #endif
247 	int                    stop;
248 } scsi_info_t;
249 
250 
251 /* synchronous transfer negotiation data */
252 typedef struct _sync_data {
253 	unsigned int SyncNegotiation;
254 #define SYNC_NOT_YET 0
255 #define SYNC_OK      1
256 #define SYNC_NG      2
257 
258 	unsigned int  SyncPeriod;
259 	unsigned int  SyncOffset;
260 	unsigned char SyncRegister;
261 	unsigned char AckWidth;
262 } sync_data;
263 
264 typedef struct _nsp_hw_data {
265 	unsigned int  BaseAddress;
266 	unsigned int  NumAddress;
267 	unsigned int  IrqNumber;
268 
269 	unsigned long MmioAddress;
270 #define NSP_MMIO_OFFSET 0x0800
271 	unsigned long MmioLength;
272 
273 	unsigned char ScsiClockDiv;
274 	unsigned char TransferMode;
275 	unsigned char ChipRev;
276 
277 	int           TimerCount;
278 	int           SelectionTimeOut;
279 	Scsi_Cmnd    *CurrentSC;
280 	//int           CurrnetTarget;
281 
282 	int           FifoCount;
283 
284 #define MSGBUF_SIZE 20
285 	unsigned char MsgBuffer[MSGBUF_SIZE];
286 	int MsgLen;
287 
288 #define N_TARGET 8
289 	sync_data     Sync[N_TARGET];
290 
291 	char nspinfo[110];     /* description */
292 	spinlock_t Lock;
293 
294 	scsi_info_t   *ScsiInfo; /* attach <-> detect glue */
295 
296 
297 #ifdef NSP_DEBUG
298 	int CmdId; /* Accepted command serial number.
299 		      Used for debugging.             */
300 #endif
301 } nsp_hw_data;
302 
303 
304 /****************************************************************************
305  *
306  */
307 
308 /* Card service functions */
309 static dev_link_t *nsp_cs_attach (void);
310 static void        nsp_cs_detach (dev_link_t *link);
311 static void        nsp_cs_release(dev_link_t *link);
312 static void        nsp_cs_config (dev_link_t *link);
313 static int         nsp_cs_event  (event_t event, int priority, event_callback_args_t *args);
314 
315 /* Linux SCSI subsystem specific functions */
316 static struct Scsi_Host *nsp_detect     (Scsi_Host_Template *sht);
317 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
318 static        int        nsp_detect_old (Scsi_Host_Template *sht);
319 static        int        nsp_release_old(struct Scsi_Host *shpnt);
320 #endif
321 static const  char      *nsp_info       (struct Scsi_Host *shpnt);
322 static        int        nsp_proc_info  (
323 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
324 	                                 struct Scsi_Host *host,
325 #endif
326 					 char   *buffer,
327 					 char  **start,
328 					 off_t   offset,
329 					 int     length,
330 #if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
331 					 int     hostno,
332 #endif
333 					 int     inout);
334 static        int        nsp_queuecommand(Scsi_Cmnd *SCpnt, void (* done)(Scsi_Cmnd *SCpnt));
335 
336 /* Error handler */
337 /*static int nsp_eh_abort       (Scsi_Cmnd *SCpnt);*/
338 /*static int nsp_eh_device_reset(Scsi_Cmnd *SCpnt);*/
339 static int nsp_eh_bus_reset    (Scsi_Cmnd *SCpnt);
340 static int nsp_eh_host_reset   (Scsi_Cmnd *SCpnt);
341 static int nsp_bus_reset       (nsp_hw_data *data);
342 
343 /* */
344 static int  nsphw_init           (nsp_hw_data *data);
345 static int  nsphw_start_selection(Scsi_Cmnd *SCpnt);
346 static void nsp_start_timer      (Scsi_Cmnd *SCpnt, int time);
347 static int  nsp_fifo_count       (Scsi_Cmnd *SCpnt);
348 static void nsp_pio_read         (Scsi_Cmnd *SCpnt);
349 static void nsp_pio_write        (Scsi_Cmnd *SCpnt);
350 static int  nsp_nexus            (Scsi_Cmnd *SCpnt);
351 static void nsp_scsi_done        (Scsi_Cmnd *SCpnt);
352 static int  nsp_analyze_sdtr     (Scsi_Cmnd *SCpnt);
353 static int  nsp_negate_signal    (Scsi_Cmnd *SCpnt, unsigned char mask, char *str);
354 static int  nsp_expect_signal    (Scsi_Cmnd *SCpnt, unsigned char current_phase, unsigned char  mask);
355 static int  nsp_xfer             (Scsi_Cmnd *SCpnt, int phase);
356 static int  nsp_dataphase_bypass (Scsi_Cmnd *SCpnt);
357 static int  nsp_reselected       (Scsi_Cmnd *SCpnt);
358 static struct Scsi_Host *nsp_detect(Scsi_Host_Template *sht);
359 
360 /* Interrupt handler */
361 //static irqreturn_t nspintr(int irq, void *dev_id, struct pt_regs *regs);
362 
363 /* Module entry point*/
364 static int  __init nsp_cs_init(void);
365 static void __exit nsp_cs_exit(void);
366 
367 
368 /* Debug */
369 #ifdef NSP_DEBUG
370 static void show_command (Scsi_Cmnd *SCpnt);
371 static void show_phase   (Scsi_Cmnd *SCpnt);
372 static void show_busphase(unsigned char stat);
373 static void show_message (nsp_hw_data *data);
374 #else
375 # define show_command(ptr)   /* */
376 # define show_phase(SCpnt)   /* */
377 # define show_busphase(stat) /* */
378 # define show_message(data)  /* */
379 #endif
380 
381 /*
382  * SCSI phase
383  */
384 enum _scsi_phase {
385 	PH_UNDETERMINED ,
386 	PH_ARBSTART     ,
387 	PH_SELSTART     ,
388 	PH_SELECTED     ,
389 	PH_COMMAND      ,
390 	PH_DATA         ,
391 	PH_STATUS       ,
392 	PH_MSG_IN       ,
393 	PH_MSG_OUT      ,
394 	PH_DISCONNECT   ,
395 	PH_RESELECT     ,
396 	PH_ABORT        ,
397 	PH_RESET
398 };
399 
400 enum _data_in_out {
401 	IO_UNKNOWN,
402 	IO_IN,
403 	IO_OUT
404 };
405 
406 enum _burst_mode {
407 	BURST_IO8   = 0,
408 	BURST_IO32  = 1,
409 	BURST_MEM32 = 2,
410 };
411 
412 
413 /**************************************************************************
414  * SCSI messaage
415  */
416 #define MSG_COMMAND_COMPLETE 0x00
417 #define MSG_EXTENDED         0x01
418 #define MSG_ABORT            0x06
419 #define MSG_NO_OPERATION     0x08
420 #define MSG_BUS_DEVICE_RESET 0x0c
421 
422 #define MSG_EXT_SDTR         0x01
423 
424 
425 /**************************************************************************
426  * Compatibility functions
427  */
428 
429 /* for Kernel 2.4 */
430 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
431 # define scsi_register_host(template)   scsi_register_module(MODULE_SCSI_HA, template)
432 # define scsi_unregister_host(template) scsi_unregister_module(MODULE_SCSI_HA, template)
433 # define scsi_host_put(host)            scsi_unregister(host)
434 
435 # define IRQ_NONE      /* */
436 # define IRQ_HANDLED   /* */
437 # define IRQ_RETVAL(x) /* */
438 
439 /* This is ad-hoc version of scsi_host_get_next() */
scsi_host_get_next(struct Scsi_Host * host)440 static inline struct Scsi_Host *scsi_host_get_next(struct Scsi_Host *host)
441 {
442 	if (host == NULL) {
443 		return scsi_hostlist;
444 	} else {
445 		return host->next;
446 	}
447 }
448 
449 /* This is ad-hoc version of scsi_host_hn_get() */
scsi_host_hn_get(unsigned short hostno)450 static inline struct Scsi_Host *scsi_host_hn_get(unsigned short hostno)
451 {
452 	struct Scsi_Host *host;
453 
454 	for (host = scsi_host_get_next(NULL); host != NULL;
455 	     host = scsi_host_get_next(host)) {
456 		if (host->host_no == hostno) {
457 			break;
458 		}
459 	}
460 
461 	return host;
462 }
463 
cs_error(client_handle_t handle,int func,int ret)464 static void cs_error(client_handle_t handle, int func, int ret)
465 {
466 	error_info_t err = { func, ret };
467 	CardServices(ReportError, handle, &err);
468 }
469 
470 /* scatter-gather table */
471 # define SG_ADDRESS(buffer) ((buffer)->address)
472 
473 /* host spin lock */
474 # define HOST_LOCK          (&io_request_lock)
475 #endif
476 
477 /* for Kernel 2.6 */
478 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
479 /* scatter-gather table */
480 # define SG_ADDRESS(buffer) ((char *) (page_address((buffer)->page)+(buffer)->offset))
481 
482 /* host spin lock */
483 # define HOST_LOCK          (((scsi_info_t *)dev_id)->host->host_lock)
484 #endif
485 
486 #endif  /*__nsp_cs__*/
487 /* end */
488