xref: /openbmc/linux/drivers/scsi/g_NCR5380.c (revision 3ca9760fdfa411f7e5db54b3437fbb858d2ec825)
1  /*
2   * Generic Generic NCR5380 driver
3   *
4   * Copyright 1993, Drew Eckhardt
5   *	Visionary Computing
6   *	(Unix and Linux consulting and custom programming)
7   *	drew@colorado.edu
8   *      +1 (303) 440-4894
9   *
10   * NCR53C400 extensions (c) 1994,1995,1996, Kevin Lentin
11   *    K.Lentin@cs.monash.edu.au
12   *
13   * NCR53C400A extensions (c) 1996, Ingmar Baumgart
14   *    ingmar@gonzo.schwaben.de
15   *
16   * DTC3181E extensions (c) 1997, Ronald van Cuijlenborg
17   * ronald.van.cuijlenborg@tip.nl or nutty@dds.nl
18   *
19   * Added ISAPNP support for DTC436 adapters,
20   * Thomas Sailer, sailer@ife.ee.ethz.ch
21   *
22   * See Documentation/scsi/g_NCR5380.txt for more info.
23   */
24  
25  #include <asm/io.h>
26  #include <linux/blkdev.h>
27  #include <linux/module.h>
28  #include <scsi/scsi_host.h>
29  #include "g_NCR5380.h"
30  #include "NCR5380.h"
31  #include <linux/init.h>
32  #include <linux/ioport.h>
33  #include <linux/isapnp.h>
34  #include <linux/interrupt.h>
35  
36  static int ncr_irq;
37  static int ncr_dma;
38  static int ncr_addr;
39  static int ncr_5380;
40  static int ncr_53c400;
41  static int ncr_53c400a;
42  static int dtc_3181e;
43  static int hp_c2502;
44  
45  static struct override {
46  	NCR5380_map_type NCR5380_map_name;
47  	int irq;
48  	int dma;
49  	int board;		/* Use NCR53c400, Ricoh, etc. extensions ? */
50  } overrides
51  #ifdef GENERIC_NCR5380_OVERRIDE
52  [] __initdata = GENERIC_NCR5380_OVERRIDE;
53  #else
54  [1] __initdata = { { 0,},};
55  #endif
56  
57  #define NO_OVERRIDES ARRAY_SIZE(overrides)
58  
59  #ifndef MODULE
60  
61  /**
62   *	internal_setup		-	handle lilo command string override
63   *	@board:	BOARD_* identifier for the board
64   *	@str: unused
65   *	@ints: numeric parameters
66   *
67   * 	Do LILO command line initialization of the overrides array. Display
68   *	errors when needed
69   *
70   *	Locks: none
71   */
72  
73  static void __init internal_setup(int board, char *str, int *ints)
74  {
75  	static int commandline_current;
76  	switch (board) {
77  	case BOARD_NCR5380:
78  		if (ints[0] != 2 && ints[0] != 3) {
79  			printk(KERN_ERR "generic_NCR5380_setup : usage ncr5380=" STRVAL(NCR5380_map_name) ",irq,dma\n");
80  			return;
81  		}
82  		break;
83  	case BOARD_NCR53C400:
84  		if (ints[0] != 2) {
85  			printk(KERN_ERR "generic_NCR53C400_setup : usage ncr53c400=" STRVAL(NCR5380_map_name) ",irq\n");
86  			return;
87  		}
88  		break;
89  	case BOARD_NCR53C400A:
90  		if (ints[0] != 2) {
91  			printk(KERN_ERR "generic_NCR53C400A_setup : usage ncr53c400a=" STRVAL(NCR5380_map_name) ",irq\n");
92  			return;
93  		}
94  		break;
95  	case BOARD_DTC3181E:
96  		if (ints[0] != 2) {
97  			printk("generic_DTC3181E_setup : usage dtc3181e=" STRVAL(NCR5380_map_name) ",irq\n");
98  			return;
99  		}
100  		break;
101  	}
102  
103  	if (commandline_current < NO_OVERRIDES) {
104  		overrides[commandline_current].NCR5380_map_name = (NCR5380_map_type) ints[1];
105  		overrides[commandline_current].irq = ints[2];
106  		if (ints[0] == 3)
107  			overrides[commandline_current].dma = ints[3];
108  		else
109  			overrides[commandline_current].dma = DMA_NONE;
110  		overrides[commandline_current].board = board;
111  		++commandline_current;
112  	}
113  }
114  
115  
116  /**
117   * 	do_NCR53C80_setup		-	set up entry point
118   *	@str: unused
119   *
120   *	Setup function invoked at boot to parse the ncr5380= command
121   *	line.
122   */
123  
124  static int __init do_NCR5380_setup(char *str)
125  {
126  	int ints[10];
127  
128  	get_options(str, ARRAY_SIZE(ints), ints);
129  	internal_setup(BOARD_NCR5380, str, ints);
130  	return 1;
131  }
132  
133  /**
134   * 	do_NCR53C400_setup		-	set up entry point
135   *	@str: unused
136   *	@ints: integer parameters from kernel setup code
137   *
138   *	Setup function invoked at boot to parse the ncr53c400= command
139   *	line.
140   */
141  
142  static int __init do_NCR53C400_setup(char *str)
143  {
144  	int ints[10];
145  
146  	get_options(str, ARRAY_SIZE(ints), ints);
147  	internal_setup(BOARD_NCR53C400, str, ints);
148  	return 1;
149  }
150  
151  /**
152   * 	do_NCR53C400A_setup	-	set up entry point
153   *	@str: unused
154   *	@ints: integer parameters from kernel setup code
155   *
156   *	Setup function invoked at boot to parse the ncr53c400a= command
157   *	line.
158   */
159  
160  static int __init do_NCR53C400A_setup(char *str)
161  {
162  	int ints[10];
163  
164  	get_options(str, ARRAY_SIZE(ints), ints);
165  	internal_setup(BOARD_NCR53C400A, str, ints);
166  	return 1;
167  }
168  
169  /**
170   * 	do_DTC3181E_setup	-	set up entry point
171   *	@str: unused
172   *	@ints: integer parameters from kernel setup code
173   *
174   *	Setup function invoked at boot to parse the dtc3181e= command
175   *	line.
176   */
177  
178  static int __init do_DTC3181E_setup(char *str)
179  {
180  	int ints[10];
181  
182  	get_options(str, ARRAY_SIZE(ints), ints);
183  	internal_setup(BOARD_DTC3181E, str, ints);
184  	return 1;
185  }
186  
187  #endif
188  
189  #ifndef SCSI_G_NCR5380_MEM
190  /*
191   * Configure I/O address of 53C400A or DTC436 by writing magic numbers
192   * to ports 0x779 and 0x379.
193   */
194  static void magic_configure(int idx, u8 irq, u8 magic[])
195  {
196  	u8 cfg = 0;
197  
198  	outb(magic[0], 0x779);
199  	outb(magic[1], 0x379);
200  	outb(magic[2], 0x379);
201  	outb(magic[3], 0x379);
202  	outb(magic[4], 0x379);
203  
204  	/* allowed IRQs for HP C2502 */
205  	if (irq != 2 && irq != 3 && irq != 4 && irq != 5 && irq != 7)
206  		irq = 0;
207  	if (idx >= 0 && idx <= 7)
208  		cfg = 0x80 | idx | (irq << 4);
209  	outb(cfg, 0x379);
210  }
211  #endif
212  
213  /**
214   * 	generic_NCR5380_detect	-	look for NCR5380 controllers
215   *	@tpnt: the scsi template
216   *
217   *	Scan for the present of NCR5380, NCR53C400, NCR53C400A, DTC3181E
218   *	and DTC436(ISAPnP) controllers. If overrides have been set we use
219   *	them.
220   *
221   *	Locks: none
222   */
223  
224  static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
225  {
226  	static int current_override;
227  	int count;
228  	unsigned int *ports;
229  	u8 *magic = NULL;
230  #ifndef SCSI_G_NCR5380_MEM
231  	int i;
232  	int port_idx = -1;
233  	unsigned long region_size;
234  #endif
235  	static unsigned int __initdata ncr_53c400a_ports[] = {
236  		0x280, 0x290, 0x300, 0x310, 0x330, 0x340, 0x348, 0x350, 0
237  	};
238  	static unsigned int __initdata dtc_3181e_ports[] = {
239  		0x220, 0x240, 0x280, 0x2a0, 0x2c0, 0x300, 0x320, 0x340, 0
240  	};
241  	static u8 ncr_53c400a_magic[] __initdata = {	/* 53C400A & DTC436 */
242  		0x59, 0xb9, 0xc5, 0xae, 0xa6
243  	};
244  	static u8 hp_c2502_magic[] __initdata = {	/* HP C2502 */
245  		0x0f, 0x22, 0xf0, 0x20, 0x80
246  	};
247  	int flags;
248  	struct Scsi_Host *instance;
249  	struct NCR5380_hostdata *hostdata;
250  #ifdef SCSI_G_NCR5380_MEM
251  	unsigned long base;
252  	void __iomem *iomem;
253  	resource_size_t iomem_size;
254  #endif
255  
256  	if (ncr_irq)
257  		overrides[0].irq = ncr_irq;
258  	if (ncr_dma)
259  		overrides[0].dma = ncr_dma;
260  	if (ncr_addr)
261  		overrides[0].NCR5380_map_name = (NCR5380_map_type) ncr_addr;
262  	if (ncr_5380)
263  		overrides[0].board = BOARD_NCR5380;
264  	else if (ncr_53c400)
265  		overrides[0].board = BOARD_NCR53C400;
266  	else if (ncr_53c400a)
267  		overrides[0].board = BOARD_NCR53C400A;
268  	else if (dtc_3181e)
269  		overrides[0].board = BOARD_DTC3181E;
270  	else if (hp_c2502)
271  		overrides[0].board = BOARD_HP_C2502;
272  #ifndef SCSI_G_NCR5380_MEM
273  	if (!current_override && isapnp_present()) {
274  		struct pnp_dev *dev = NULL;
275  		count = 0;
276  		while ((dev = pnp_find_dev(NULL, ISAPNP_VENDOR('D', 'T', 'C'), ISAPNP_FUNCTION(0x436e), dev))) {
277  			if (count >= NO_OVERRIDES)
278  				break;
279  			if (pnp_device_attach(dev) < 0)
280  				continue;
281  			if (pnp_activate_dev(dev) < 0) {
282  				printk(KERN_ERR "dtc436e probe: activate failed\n");
283  				pnp_device_detach(dev);
284  				continue;
285  			}
286  			if (!pnp_port_valid(dev, 0)) {
287  				printk(KERN_ERR "dtc436e probe: no valid port\n");
288  				pnp_device_detach(dev);
289  				continue;
290  			}
291  			if (pnp_irq_valid(dev, 0))
292  				overrides[count].irq = pnp_irq(dev, 0);
293  			else
294  				overrides[count].irq = NO_IRQ;
295  			if (pnp_dma_valid(dev, 0))
296  				overrides[count].dma = pnp_dma(dev, 0);
297  			else
298  				overrides[count].dma = DMA_NONE;
299  			overrides[count].NCR5380_map_name = (NCR5380_map_type) pnp_port_start(dev, 0);
300  			overrides[count].board = BOARD_DTC3181E;
301  			count++;
302  		}
303  	}
304  #endif
305  
306  	for (count = 0; current_override < NO_OVERRIDES; ++current_override) {
307  		if (!(overrides[current_override].NCR5380_map_name))
308  			continue;
309  
310  		ports = NULL;
311  		flags = 0;
312  		switch (overrides[current_override].board) {
313  		case BOARD_NCR5380:
314  			flags = FLAG_NO_PSEUDO_DMA | FLAG_DMA_FIXUP;
315  			break;
316  		case BOARD_NCR53C400A:
317  			ports = ncr_53c400a_ports;
318  			magic = ncr_53c400a_magic;
319  			break;
320  		case BOARD_HP_C2502:
321  			ports = ncr_53c400a_ports;
322  			magic = hp_c2502_magic;
323  			break;
324  		case BOARD_DTC3181E:
325  			ports = dtc_3181e_ports;
326  			magic = ncr_53c400a_magic;
327  			break;
328  		}
329  
330  #ifndef SCSI_G_NCR5380_MEM
331  		if (ports && magic) {
332  			/* wakeup sequence for the NCR53C400A and DTC3181E */
333  
334  			/* Disable the adapter and look for a free io port */
335  			magic_configure(-1, 0, magic);
336  
337  			region_size = 16;
338  
339  			if (overrides[current_override].NCR5380_map_name != PORT_AUTO)
340  				for (i = 0; ports[i]; i++) {
341  					if (!request_region(ports[i], region_size, "ncr53c80"))
342  						continue;
343  					if (overrides[current_override].NCR5380_map_name == ports[i])
344  						break;
345  					release_region(ports[i], region_size);
346  			} else
347  				for (i = 0; ports[i]; i++) {
348  					if (!request_region(ports[i], region_size, "ncr53c80"))
349  						continue;
350  					if (inb(ports[i]) == 0xff)
351  						break;
352  					release_region(ports[i], region_size);
353  				}
354  			if (ports[i]) {
355  				/* At this point we have our region reserved */
356  				magic_configure(i, 0, magic); /* no IRQ yet */
357  				outb(0xc0, ports[i] + 9);
358  				if (inb(ports[i] + 9) != 0x80)
359  					continue;
360  				overrides[current_override].NCR5380_map_name = ports[i];
361  				port_idx = i;
362  			} else
363  				continue;
364  		}
365  		else
366  		{
367  			/* Not a 53C400A style setup - just grab */
368  			region_size = 8;
369  			if (!request_region(overrides[current_override].NCR5380_map_name,
370  			                    region_size, "ncr5380"))
371  				continue;
372  		}
373  #else
374  		base = overrides[current_override].NCR5380_map_name;
375  		iomem_size = NCR53C400_region_size;
376  		if (!request_mem_region(base, iomem_size, "ncr5380"))
377  			continue;
378  		iomem = ioremap(base, iomem_size);
379  		if (!iomem) {
380  			release_mem_region(base, iomem_size);
381  			continue;
382  		}
383  #endif
384  		instance = scsi_register(tpnt, sizeof(struct NCR5380_hostdata));
385  		if (instance == NULL)
386  			goto out_release;
387  		hostdata = shost_priv(instance);
388  
389  #ifndef SCSI_G_NCR5380_MEM
390  		instance->io_port = overrides[current_override].NCR5380_map_name;
391  		instance->n_io_port = region_size;
392  		hostdata->io_width = 1; /* 8-bit PDMA by default */
393  
394  		/*
395  		 * On NCR53C400 boards, NCR5380 registers are mapped 8 past
396  		 * the base address.
397  		 */
398  		switch (overrides[current_override].board) {
399  		case BOARD_NCR53C400:
400  			instance->io_port += 8;
401  			hostdata->c400_ctl_status = 0;
402  			hostdata->c400_blk_cnt = 1;
403  			hostdata->c400_host_buf = 4;
404  			break;
405  		case BOARD_DTC3181E:
406  			hostdata->io_width = 2;	/* 16-bit PDMA */
407  			/* fall through */
408  		case BOARD_NCR53C400A:
409  		case BOARD_HP_C2502:
410  			hostdata->c400_ctl_status = 9;
411  			hostdata->c400_blk_cnt = 10;
412  			hostdata->c400_host_buf = 8;
413  			break;
414  		}
415  #else
416  		instance->base = overrides[current_override].NCR5380_map_name;
417  		hostdata->iomem = iomem;
418  		hostdata->iomem_size = iomem_size;
419  		switch (overrides[current_override].board) {
420  		case BOARD_NCR53C400:
421  			hostdata->c400_ctl_status = 0x100;
422  			hostdata->c400_blk_cnt = 0x101;
423  			hostdata->c400_host_buf = 0x104;
424  			break;
425  		case BOARD_DTC3181E:
426  		case BOARD_NCR53C400A:
427  		case BOARD_HP_C2502:
428  			pr_err(DRV_MODULE_NAME ": unknown register offsets\n");
429  			goto out_unregister;
430  		}
431  #endif
432  
433  		if (NCR5380_init(instance, flags | FLAG_LATE_DMA_SETUP))
434  			goto out_unregister;
435  
436  		switch (overrides[current_override].board) {
437  		case BOARD_NCR53C400:
438  		case BOARD_DTC3181E:
439  		case BOARD_NCR53C400A:
440  		case BOARD_HP_C2502:
441  			NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
442  		}
443  
444  		NCR5380_maybe_reset_bus(instance);
445  
446  		if (overrides[current_override].irq != IRQ_AUTO)
447  			instance->irq = overrides[current_override].irq;
448  		else
449  			instance->irq = NCR5380_probe_irq(instance, 0xffff);
450  
451  		/* Compatibility with documented NCR5380 kernel parameters */
452  		if (instance->irq == 255)
453  			instance->irq = NO_IRQ;
454  
455  		if (instance->irq != NO_IRQ) {
456  #ifndef SCSI_G_NCR5380_MEM
457  			/* set IRQ for HP C2502 */
458  			if (overrides[current_override].board == BOARD_HP_C2502)
459  				magic_configure(port_idx, instance->irq, magic);
460  #endif
461  			if (request_irq(instance->irq, generic_NCR5380_intr,
462  					0, "NCR5380", instance)) {
463  				printk(KERN_WARNING "scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq);
464  				instance->irq = NO_IRQ;
465  			}
466  		}
467  
468  		if (instance->irq == NO_IRQ) {
469  			printk(KERN_INFO "scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
470  			printk(KERN_INFO "scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
471  		}
472  
473  		++current_override;
474  		++count;
475  	}
476  	return count;
477  
478  out_unregister:
479  	scsi_unregister(instance);
480  out_release:
481  #ifndef SCSI_G_NCR5380_MEM
482  	release_region(overrides[current_override].NCR5380_map_name, region_size);
483  #else
484  	iounmap(iomem);
485  	release_mem_region(base, iomem_size);
486  #endif
487  	return count;
488  }
489  
490  /**
491   *	generic_NCR5380_release_resources	-	free resources
492   *	@instance: host adapter to clean up
493   *
494   *	Free the generic interface resources from this adapter.
495   *
496   *	Locks: none
497   */
498  
499  static int generic_NCR5380_release_resources(struct Scsi_Host *instance)
500  {
501  	if (instance->irq != NO_IRQ)
502  		free_irq(instance->irq, instance);
503  	NCR5380_exit(instance);
504  #ifndef SCSI_G_NCR5380_MEM
505  	release_region(instance->io_port, instance->n_io_port);
506  #else
507  	{
508  		struct NCR5380_hostdata *hostdata = shost_priv(instance);
509  
510  		iounmap(hostdata->iomem);
511  		release_mem_region(instance->base, hostdata->iomem_size);
512  	}
513  #endif
514  	return 0;
515  }
516  
517  /**
518   *	generic_NCR5380_pread - pseudo DMA read
519   *	@instance: adapter to read from
520   *	@dst: buffer to read into
521   *	@len: buffer length
522   *
523   *	Perform a pseudo DMA mode read from an NCR53C400 or equivalent
524   *	controller
525   */
526  
527  static inline int generic_NCR5380_pread(struct Scsi_Host *instance,
528                                          unsigned char *dst, int len)
529  {
530  	struct NCR5380_hostdata *hostdata = shost_priv(instance);
531  	int blocks = len / 128;
532  	int start = 0;
533  
534  	NCR5380_write(hostdata->c400_ctl_status, CSR_BASE | CSR_TRANS_DIR);
535  	NCR5380_write(hostdata->c400_blk_cnt, blocks);
536  	while (1) {
537  		if (NCR5380_read(hostdata->c400_blk_cnt) == 0)
538  			break;
539  		if (NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ) {
540  			printk(KERN_ERR "53C400r: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
541  			return -1;
542  		}
543  		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
544  			; /* FIXME - no timeout */
545  
546  #ifndef SCSI_G_NCR5380_MEM
547  		if (hostdata->io_width == 2)
548  			insw(instance->io_port + hostdata->c400_host_buf,
549  							dst + start, 64);
550  		else
551  			insb(instance->io_port + hostdata->c400_host_buf,
552  							dst + start, 128);
553  #else
554  		/* implies SCSI_G_NCR5380_MEM */
555  		memcpy_fromio(dst + start,
556  		              hostdata->iomem + NCR53C400_host_buffer, 128);
557  #endif
558  		start += 128;
559  		blocks--;
560  	}
561  
562  	if (blocks) {
563  		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
564  			; /* FIXME - no timeout */
565  
566  #ifndef SCSI_G_NCR5380_MEM
567  		if (hostdata->io_width == 2)
568  			insw(instance->io_port + hostdata->c400_host_buf,
569  							dst + start, 64);
570  		else
571  			insb(instance->io_port + hostdata->c400_host_buf,
572  							dst + start, 128);
573  #else
574  		/* implies SCSI_G_NCR5380_MEM */
575  		memcpy_fromio(dst + start,
576  		              hostdata->iomem + NCR53C400_host_buffer, 128);
577  #endif
578  		start += 128;
579  		blocks--;
580  	}
581  
582  	if (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ))
583  		printk("53C400r: no 53C80 gated irq after transfer");
584  
585  	/* wait for 53C80 registers to be available */
586  	while (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG))
587  		;
588  
589  	if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER))
590  		printk(KERN_ERR "53C400r: no end dma signal\n");
591  
592  	return 0;
593  }
594  
595  /**
596   *	generic_NCR5380_pwrite - pseudo DMA write
597   *	@instance: adapter to read from
598   *	@dst: buffer to read into
599   *	@len: buffer length
600   *
601   *	Perform a pseudo DMA mode read from an NCR53C400 or equivalent
602   *	controller
603   */
604  
605  static inline int generic_NCR5380_pwrite(struct Scsi_Host *instance,
606                                           unsigned char *src, int len)
607  {
608  	struct NCR5380_hostdata *hostdata = shost_priv(instance);
609  	int blocks = len / 128;
610  	int start = 0;
611  
612  	NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
613  	NCR5380_write(hostdata->c400_blk_cnt, blocks);
614  	while (1) {
615  		if (NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ) {
616  			printk(KERN_ERR "53C400w: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
617  			return -1;
618  		}
619  
620  		if (NCR5380_read(hostdata->c400_blk_cnt) == 0)
621  			break;
622  		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
623  			; // FIXME - timeout
624  #ifndef SCSI_G_NCR5380_MEM
625  		if (hostdata->io_width == 2)
626  			outsw(instance->io_port + hostdata->c400_host_buf,
627  							src + start, 64);
628  		else
629  			outsb(instance->io_port + hostdata->c400_host_buf,
630  							src + start, 128);
631  #else
632  		/* implies SCSI_G_NCR5380_MEM */
633  		memcpy_toio(hostdata->iomem + NCR53C400_host_buffer,
634  		            src + start, 128);
635  #endif
636  		start += 128;
637  		blocks--;
638  	}
639  	if (blocks) {
640  		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
641  			; // FIXME - no timeout
642  
643  #ifndef SCSI_G_NCR5380_MEM
644  		if (hostdata->io_width == 2)
645  			outsw(instance->io_port + hostdata->c400_host_buf,
646  							src + start, 64);
647  		else
648  			outsb(instance->io_port + hostdata->c400_host_buf,
649  							src + start, 128);
650  #else
651  		/* implies SCSI_G_NCR5380_MEM */
652  		memcpy_toio(hostdata->iomem + NCR53C400_host_buffer,
653  		            src + start, 128);
654  #endif
655  		start += 128;
656  		blocks--;
657  	}
658  
659  	/* wait for 53C80 registers to be available */
660  	while (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)) {
661  		udelay(4); /* DTC436 chip hangs without this */
662  		/* FIXME - no timeout */
663  	}
664  
665  	if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER)) {
666  		printk(KERN_ERR "53C400w: no end dma signal\n");
667  	}
668  
669  	while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT))
670  		; 	// TIMEOUT
671  	return 0;
672  }
673  
674  static int generic_NCR5380_dma_xfer_len(struct Scsi_Host *instance,
675                                          struct scsi_cmnd *cmd)
676  {
677  	struct NCR5380_hostdata *hostdata = shost_priv(instance);
678  	int transfersize = cmd->transfersize;
679  
680  	if (hostdata->flags & FLAG_NO_PSEUDO_DMA)
681  		return 0;
682  
683  	/* Limit transfers to 32K, for xx400 & xx406
684  	 * pseudoDMA that transfers in 128 bytes blocks.
685  	 */
686  	if (transfersize > 32 * 1024 && cmd->SCp.this_residual &&
687  	    !(cmd->SCp.this_residual % transfersize))
688  		transfersize = 32 * 1024;
689  
690  	/* 53C400 datasheet: non-modulo-128-byte transfers should use PIO */
691  	if (transfersize % 128)
692  		transfersize = 0;
693  
694  	return transfersize;
695  }
696  
697  /*
698   *	Include the NCR5380 core code that we build our driver around
699   */
700  
701  #include "NCR5380.c"
702  
703  static struct scsi_host_template driver_template = {
704  	.proc_name		= DRV_MODULE_NAME,
705  	.name			= "Generic NCR5380/NCR53C400 SCSI",
706  	.detect			= generic_NCR5380_detect,
707  	.release		= generic_NCR5380_release_resources,
708  	.info			= generic_NCR5380_info,
709  	.queuecommand		= generic_NCR5380_queue_command,
710  	.eh_abort_handler	= generic_NCR5380_abort,
711  	.eh_bus_reset_handler	= generic_NCR5380_bus_reset,
712  	.can_queue		= 16,
713  	.this_id		= 7,
714  	.sg_tablesize		= SG_ALL,
715  	.cmd_per_lun		= 2,
716  	.use_clustering		= DISABLE_CLUSTERING,
717  	.cmd_size		= NCR5380_CMD_SIZE,
718  	.max_sectors		= 128,
719  };
720  
721  #include "scsi_module.c"
722  
723  module_param(ncr_irq, int, 0);
724  module_param(ncr_dma, int, 0);
725  module_param(ncr_addr, int, 0);
726  module_param(ncr_5380, int, 0);
727  module_param(ncr_53c400, int, 0);
728  module_param(ncr_53c400a, int, 0);
729  module_param(dtc_3181e, int, 0);
730  module_param(hp_c2502, int, 0);
731  MODULE_LICENSE("GPL");
732  
733  #if !defined(SCSI_G_NCR5380_MEM) && defined(MODULE)
734  static struct isapnp_device_id id_table[] = {
735  	{
736  	 ISAPNP_ANY_ID, ISAPNP_ANY_ID,
737  	 ISAPNP_VENDOR('D', 'T', 'C'), ISAPNP_FUNCTION(0x436e),
738  	 0},
739  	{0}
740  };
741  
742  MODULE_DEVICE_TABLE(isapnp, id_table);
743  #endif
744  
745  __setup("ncr5380=", do_NCR5380_setup);
746  __setup("ncr53c400=", do_NCR53C400_setup);
747  __setup("ncr53c400a=", do_NCR53C400A_setup);
748  __setup("dtc3181e=", do_DTC3181E_setup);
749