This source file includes following definitions.
- enable_board
- init_board
- pas16_hw_detect
- pas16_setup
- pas16_detect
- pas16_biosparam
- NCR5380_pread
- NCR5380_pwrite
1 #define AUTOSENSE
2 #define PSEUDO_DMA
3 #define FOO
4 #define UNSAFE
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105 #include <asm/system.h>
106 #include <linux/signal.h>
107 #include <linux/sched.h>
108 #include <asm/io.h>
109 #include "../block/blk.h"
110 #include "scsi.h"
111 #include "hosts.h"
112 #include "pas16.h"
113 #define AUTOPROBE_IRQ
114 #include "NCR5380.h"
115 #include "constants.h"
116 #include "sd.h"
117
118
119 int scsi_irq_translate[] =
120 { 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 0, 10, 11 };
121
122
123
124
125
126
127 int default_irqs[] = { PAS16_DEFAULT_BOARD_1_IRQ,
128 PAS16_DEFAULT_BOARD_2_IRQ,
129 PAS16_DEFAULT_BOARD_3_IRQ,
130 PAS16_DEFAULT_BOARD_4_IRQ
131 };
132
133 static struct override {
134 unsigned short io_port;
135 int irq;
136 } overrides
137 #ifdef PAS16_OVERRIDE
138 [] = PAS16_OVERRIDE;
139 #else
140 [4] = {{0,IRQ_AUTO}, {0,IRQ_AUTO}, {0,IRQ_AUTO},
141 {0,IRQ_AUTO}};
142 #endif
143
144 #define NO_OVERRIDES (sizeof(overrides) / sizeof(struct override))
145
146 static struct base {
147 unsigned short io_port;
148 int noauto;
149 } bases[] = { {PAS16_DEFAULT_BASE_1, 0},
150 {PAS16_DEFAULT_BASE_2, 0},
151 {PAS16_DEFAULT_BASE_3, 0},
152 {PAS16_DEFAULT_BASE_4, 0}
153 };
154
155 #define NO_BASES (sizeof (bases) / sizeof (struct base))
156
157 unsigned short pas16_offset[ 8 ] =
158 {
159 0x1c00,
160 0x1c01,
161 0x1c02,
162 0x1c03,
163 0x3c00,
164 0x3c01,
165 0x3c02,
166
167
168 0x3c03,
169
170
171 };
172
173
174
175
176
177
178
179
180
181
182
183
184 void enable_board( int board_num, unsigned short port )
185 {
186 outb( 0xbc + board_num, MASTER_ADDRESS_PTR );
187 outb( port >> 2, MASTER_ADDRESS_PTR );
188 }
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203 void init_board( unsigned short io_port, int irq, int force_irq )
204 {
205 unsigned int tmp;
206 unsigned int pas_irq_code;
207
208
209
210 outb( 0x30, io_port + P_TIMEOUT_COUNTER_REG );
211 outb( 0x01, io_port + P_TIMEOUT_STATUS_REG_OFFSET );
212 outb( 0x01, io_port + WAIT_STATE );
213
214 NCR5380_read( RESET_PARITY_INTERRUPT_REG );
215
216
217
218
219 pas_irq_code = ( irq < 16 ) ? scsi_irq_translate[irq] : 0;
220 tmp = inb( io_port + IO_CONFIG_3 );
221
222 if( (( tmp & 0x0f ) == pas_irq_code) && pas_irq_code > 0
223 && !force_irq )
224 {
225 printk( "pas16: WARNING: Can't use same irq as sound "
226 "driver -- interrupts disabled\n" );
227
228 outb( 0x4d, io_port + SYS_CONFIG_4 );
229 }
230 else
231 {
232 tmp = ( tmp & 0x0f ) | ( pas_irq_code << 4 );
233 outb( tmp, io_port + IO_CONFIG_3 );
234
235
236 outb( 0x6d, io_port + SYS_CONFIG_4 );
237 }
238 }
239
240
241
242
243
244
245
246
247
248
249
250
251 int pas16_hw_detect( unsigned short board_num )
252 {
253 unsigned char board_rev, tmp;
254 unsigned short io_port = bases[ board_num ].io_port;
255
256
257
258
259
260
261
262
263 enable_board( board_num, io_port );
264
265
266 board_rev = inb( io_port + PCB_CONFIG );
267
268 if( board_rev == 0xff )
269 return 0;
270
271 tmp = board_rev ^ 0xe0;
272
273 outb( tmp, io_port + PCB_CONFIG );
274 tmp = inb( io_port + PCB_CONFIG );
275 outb( board_rev, io_port + PCB_CONFIG );
276
277 if( board_rev != tmp )
278 return 0;
279
280 if( ( inb( io_port + OPERATION_MODE_1 ) & 0x03 ) != 0x03 )
281 return 0;
282
283
284
285
286
287
288 outb( 0x01, io_port + WAIT_STATE );
289 NCR5380_write( MODE_REG, 0x20 );
290 if( NCR5380_read( MODE_REG ) != 0x20 )
291 return 0;
292 NCR5380_write( MODE_REG, 0x00 );
293 if( NCR5380_read( MODE_REG ) != 0x00 )
294 return 0;
295
296 return 1;
297 }
298
299
300
301
302
303
304
305
306
307
308
309
310 void pas16_setup(char *str, int *ints) {
311 static int commandline_current = 0;
312 int i;
313 if (ints[0] != 2)
314 printk("pas16_setup : usage pas16=io_port,irq\n");
315 else
316 if (commandline_current < NO_OVERRIDES) {
317 overrides[commandline_current].io_port = (unsigned short) ints[1];
318 overrides[commandline_current].irq = ints[2];
319 for (i = 0; i < NO_BASES; ++i)
320 if (bases[i].io_port == (unsigned short) ints[1]) {
321 bases[i].noauto = 1;
322 break;
323 }
324 ++commandline_current;
325 }
326 }
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341 int pas16_detect(Scsi_Host_Template * tpnt) {
342 static int current_override = 0;
343 static unsigned short current_base = 0;
344 struct Scsi_Host *instance;
345 unsigned short io_port;
346 int count;
347
348 for (count = 0; current_override < NO_OVERRIDES; ++current_override) {
349 io_port = 0;
350
351 if (overrides[current_override].io_port)
352 {
353 io_port = overrides[current_override].io_port;
354 enable_board( current_override, io_port );
355 init_board( io_port, overrides[current_override].irq, 1 );
356 }
357 else
358 for (; !io_port && (current_base < NO_BASES); ++current_base) {
359 #if (PDEBUG & PDEBUG_INIT)
360 printk("scsi-pas16 : probing io_port %04x\n", (unsigned int) bases[current_base].io_port);
361 #endif
362 if ( !bases[current_base].noauto &&
363 pas16_hw_detect( current_base ) ){
364 io_port = bases[current_base].io_port;
365 init_board( io_port, default_irqs[ current_base ], 0 );
366 #if (PDEBUG & PDEBUG_INIT)
367 printk("scsi-pas16 : detected board.\n");
368 #endif
369 }
370 }
371
372
373 #if defined(PDEBUG) && (PDEBUG & PDEBUG_INIT)
374 printk("scsi-pas16 : io_port = %04x\n", (unsigned int) io_port);
375 #endif
376
377 if (!io_port)
378 break;
379
380 instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
381 instance->io_port = io_port;
382
383 NCR5380_init(instance, 0);
384
385 if (overrides[current_override].irq != IRQ_AUTO)
386 instance->irq = overrides[current_override].irq;
387 else
388 instance->irq = NCR5380_probe_irq(instance, PAS16_IRQS);
389
390 if (instance->irq != IRQ_NONE)
391 if (request_irq(instance->irq, pas16_intr, SA_INTERRUPT, "pas16")) {
392 printk("scsi%d : IRQ%d not free, interrupts disabled\n",
393 instance->host_no, instance->irq);
394 instance->irq = IRQ_NONE;
395 }
396
397 if (instance->irq == IRQ_NONE) {
398 printk("scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
399 printk("scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
400
401 outb( 0x4d, io_port + SYS_CONFIG_4 );
402 outb( (inb(io_port + IO_CONFIG_3) & 0x0f), io_port + IO_CONFIG_3 );
403 }
404
405 #if defined(PDEBUG) && (PDEBUG & PDEBUG_INIT)
406 printk("scsi%d : irq = %d\n", instance->host_no, instance->irq);
407 #endif
408
409 printk("scsi%d : at 0x%04x", instance->host_no, (int)
410 instance->io_port);
411 if (instance->irq == IRQ_NONE)
412 printk (" interrupts disabled");
413 else
414 printk (" irq %d", instance->irq);
415 printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d",
416 CAN_QUEUE, CMD_PER_LUN, PAS16_PUBLIC_RELEASE);
417 NCR5380_print_options(instance);
418 printk("\n");
419
420 ++current_override;
421 ++count;
422 }
423 return count;
424 }
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446 int pas16_biosparam(Disk * disk, int dev, int * ip)
447 {
448 int size = disk->capacity;
449 ip[0] = 64;
450 ip[1] = 32;
451 ip[2] = size >> 11;
452 if( ip[2] > 1024 ) {
453 ip[0]=255;
454 ip[1]=63;
455 ip[2]=size/(63*255);
456 if( ip[2] > 1023 )
457 ip[2] = 1023;
458 }
459
460 return 0;
461 }
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476 static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst,
477 int len) {
478 register unsigned char *d = dst;
479 register unsigned short reg = (unsigned short) (instance->io_port +
480 P_DATA_REG_OFFSET);
481 register i = len;
482
483 while ( !(inb(instance->io_port + P_STATUS_REG_OFFSET) & P_ST_RDY) );
484
485 insb( reg, d, i );
486
487 if ( inb(instance->io_port + P_TIMEOUT_STATUS_REG_OFFSET) & P_TS_TIM) {
488 outb( P_TS_CT, instance->io_port + P_TIMEOUT_STATUS_REG_OFFSET);
489 printk("scsi%d : watchdog timer fired in NCR5380_pread()\n",
490 instance->host_no);
491 return -1;
492 } else
493 return 0;
494 }
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509 static inline int NCR5380_pwrite (struct Scsi_Host *instance, unsigned char *src,
510 int len) {
511 register unsigned char *s = src;
512 register unsigned short reg = (instance->io_port + P_DATA_REG_OFFSET);
513 register i = len;
514
515 while ( !((inb(instance->io_port + P_STATUS_REG_OFFSET)) & P_ST_RDY) );
516
517 outsb( reg, s, i );
518
519 if (inb(instance->io_port + P_TIMEOUT_STATUS_REG_OFFSET) & P_TS_TIM) {
520 outb( P_TS_CT, instance->io_port + P_TIMEOUT_STATUS_REG_OFFSET);
521 printk("scsi%d : watchdog timer fired in NCR5380_pwrite()\n",
522 instance->host_no);
523 return -1;
524 } else
525 return 0;
526 }
527
528 #include "NCR5380.c"