File: /usr/src/linux/drivers/block/xd.c

1     /*
2      * This file contains the driver for an XT hard disk controller
3      * (at least the DTC 5150X) for Linux.
4      *
5      * Author: Pat Mackinlay, pat@it.com.au
6      * Date: 29/09/92
7      * 
8      * Revised: 01/01/93, ...
9      *
10      * Ref: DTC 5150X Controller Specification (thanks to Kevin Fowler,
11      *   kevinf@agora.rain.com)
12      * Also thanks to: Salvador Abreu, Dave Thaler, Risto Kankkunen and
13      *   Wim Van Dorst.
14      *
15      * Revised: 04/04/94 by Risto Kankkunen
16      *   Moved the detection code from xd_init() to xd_geninit() as it needed
17      *   interrupts enabled and Linus didn't want to enable them in that first
18      *   phase. xd_geninit() is the place to do these kinds of things anyway,
19      *   he says.
20      *
21      * Modularized: 04/10/96 by Todd Fries, tfries@umr.edu
22      *
23      * Revised: 13/12/97 by Andrzej Krzysztofowicz, ankry@mif.pg.gda.pl
24      *   Fixed some problems with disk initialization and module initiation.
25      *   Added support for manual geometry setting (except Seagate controllers)
26      *   in form:
27      *      xd_geo=<cyl_xda>,<head_xda>,<sec_xda>[,<cyl_xdb>,<head_xdb>,<sec_xdb>]
28      *   Recovered DMA access. Abridged messages. Added support for DTC5051CX,
29      *   WD1002-27X & XEBEC controllers. Driver uses now some jumper settings.
30      *   Extended ioctl() support.
31      *
32      * Bugfix: 15/02/01, Paul G. - inform queue layer of tiny xd_maxsect.
33      *
34      */
35     
36     #include <linux/module.h>
37     #include <linux/errno.h>
38     #include <linux/sched.h>
39     #include <linux/mm.h>
40     #include <linux/fs.h>
41     #include <linux/kernel.h>
42     #include <linux/timer.h>
43     #include <linux/genhd.h>
44     #include <linux/hdreg.h>
45     #include <linux/ioport.h>
46     #include <linux/init.h>
47     #include <linux/devfs_fs_kernel.h>
48     
49     #include <asm/system.h>
50     #include <asm/io.h>
51     #include <asm/uaccess.h>
52     #include <asm/dma.h>
53     
54     #define MAJOR_NR XT_DISK_MAJOR
55     #include <linux/blk.h>
56     #include <linux/blkpg.h>
57     
58     #include "xd.h"
59     
60     #define XD_DONT_USE_DMA		0  /* Initial value. may be overriden using
61     				      "nodma" module option */
62     #define XD_INIT_DISK_DELAY	(30*HZ/1000)  /* 30 ms delay during disk initialization */
63     
64     /* Above may need to be increased if a problem with the 2nd drive detection
65        (ST11M controller) or resetting a controller (WD) appears */
66     
67     XD_INFO xd_info[XD_MAXDRIVES];
68     
69     /* If you try this driver and find that your card is not detected by the driver at bootup, you need to add your BIOS
70        signature and details to the following list of signatures. A BIOS signature is a string embedded into the first
71        few bytes of your controller's on-board ROM BIOS. To find out what yours is, use something like MS-DOS's DEBUG
72        command. Run DEBUG, and then you can examine your BIOS signature with:
73     
74     	d xxxx:0000
75     
76        where xxxx is the segment of your controller (like C800 or D000 or something). On the ASCII dump at the right, you should
77        be able to see a string mentioning the manufacturer's copyright etc. Add this string into the table below. The parameters
78        in the table are, in order:
79     
80     	offset			; this is the offset (in bytes) from the start of your ROM where the signature starts
81     	signature		; this is the actual text of the signature
82     	xd_?_init_controller	; this is the controller init routine used by your controller
83     	xd_?_init_drive		; this is the drive init routine used by your controller
84     
85        The controllers directly supported at the moment are: DTC 5150x, WD 1004A27X, ST11M/R and override. If your controller is
86        made by the same manufacturer as one of these, try using the same init routines as they do. If that doesn't work, your
87        best bet is to use the "override" routines. These routines use a "portable" method of getting the disk's geometry, and
88        may work with your card. If none of these seem to work, try sending me some email and I'll see what I can do <grin>.
89     
90        NOTE: You can now specify your XT controller's parameters from the command line in the form xd=TYPE,IRQ,IO,DMA. The driver
91        should be able to detect your drive's geometry from this info. (eg: xd=0,5,0x320,3 is the "standard"). */
92     
93     #include <asm/page.h>
94     #define xd_dma_mem_alloc(size) __get_dma_pages(GFP_KERNEL,get_order(size))
95     #define xd_dma_mem_free(addr, size) free_pages(addr, get_order(size))
96     static char *xd_dma_buffer = 0;
97     
98     static XD_SIGNATURE xd_sigs[] __initdata = {
99     	{ 0x0000,"Override geometry handler",NULL,xd_override_init_drive,"n unknown" }, /* Pat Mackinlay, pat@it.com.au */
100     	{ 0x0008,"[BXD06 (C) DTC 17-MAY-1985]",xd_dtc_init_controller,xd_dtc5150cx_init_drive," DTC 5150CX" }, /* Andrzej Krzysztofowicz, ankry@mif.pg.gda.pl */
101     	{ 0x000B,"CRD18A   Not an IBM rom. (C) Copyright Data Technology Corp. 05/31/88",xd_dtc_init_controller,xd_dtc_init_drive," DTC 5150X" }, /* Todd Fries, tfries@umr.edu */
102     	{ 0x000B,"CXD23A Not an IBM ROM (C)Copyright Data Technology Corp 12/03/88",xd_dtc_init_controller,xd_dtc_init_drive," DTC 5150X" }, /* Pat Mackinlay, pat@it.com.au */
103     	{ 0x0008,"07/15/86(C) Copyright 1986 Western Digital Corp.",xd_wd_init_controller,xd_wd_init_drive," Western Dig. 1002-27X" }, /* Andrzej Krzysztofowicz, ankry@mif.pg.gda.pl */
104     	{ 0x0008,"06/24/88(C) Copyright 1988 Western Digital Corp.",xd_wd_init_controller,xd_wd_init_drive," Western Dig. WDXT-GEN2" }, /* Dan Newcombe, newcombe@aa.csc.peachnet.edu */
105     	{ 0x0015,"SEAGATE ST11 BIOS REVISION",xd_seagate_init_controller,xd_seagate_init_drive," Seagate ST11M/R" }, /* Salvador Abreu, spa@fct.unl.pt */
106     	{ 0x0010,"ST11R BIOS",xd_seagate_init_controller,xd_seagate_init_drive," Seagate ST11M/R" }, /* Risto Kankkunen, risto.kankkunen@cs.helsinki.fi */
107     	{ 0x0010,"ST11 BIOS v1.7",xd_seagate_init_controller,xd_seagate_init_drive," Seagate ST11R" }, /* Alan Hourihane, alanh@fairlite.demon.co.uk */
108     	{ 0x1000,"(c)Copyright 1987 SMS",xd_omti_init_controller,xd_omti_init_drive,"n OMTI 5520" }, /* Dirk Melchers, dirk@merlin.nbg.sub.org */
109     	{ 0x0006,"COPYRIGHT XEBEC (C) 1984",xd_xebec_init_controller,xd_xebec_init_drive," XEBEC" }, /* Andrzej Krzysztofowicz, ankry@mif.pg.gda.pl */
110     };
111     
112     static unsigned int xd_bases[] __initdata =
113     {
114     	0xC8000, 0xCA000, 0xCC000,
115     	0xCE000, 0xD0000, 0xD2000,
116     	0xD4000, 0xD6000, 0xD8000,
117     	0xDA000, 0xDC000, 0xDE000,
118     	0xE0000
119     };
120     
121     static struct hd_struct xd_struct[XD_MAXDRIVES << 6];
122     static int xd_sizes[XD_MAXDRIVES << 6], xd_access[XD_MAXDRIVES];
123     static int xd_blocksizes[XD_MAXDRIVES << 6];
124     static int xd_maxsect[XD_MAXDRIVES << 6];
125     
126     extern struct block_device_operations xd_fops;
127     
128     static struct gendisk xd_gendisk = {
129     	major:		MAJOR_NR,
130     	major_name:	"xd",
131     	minor_shift:	6,
132     	max_p:		1 << 6,
133     	part:		xd_struct,
134     	sizes:		xd_sizes,
135     	real_devices:	(void *)xd_info,
136     	fops:		&xd_fops,
137     };
138     
139     static struct block_device_operations xd_fops = {
140     	open:		xd_open,
141     	release:	xd_release,
142     	ioctl:		xd_ioctl,
143     };
144     static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int);
145     static DECLARE_WAIT_QUEUE_HEAD(xd_wait_open);
146     static u_char xd_valid[XD_MAXDRIVES] = { 0,0 };
147     static u_char xd_drives, xd_irq = 5, xd_dma = 3, xd_maxsectors;
148     static u_char xd_override __initdata = 0, xd_type __initdata = 0;
149     static u_short xd_iobase = 0x320;
150     static int xd_geo[XD_MAXDRIVES*3] __initdata = { 0, };
151     
152     static volatile int xdc_busy;
153     static DECLARE_WAIT_QUEUE_HEAD(xdc_wait);
154     
155     static struct timer_list xd_timer, xd_watchdog_int;
156     
157     static volatile u_char xd_error;
158     static int nodma = XD_DONT_USE_DMA;
159     
160     static devfs_handle_t devfs_handle = NULL;
161     
162     /* xd_init: register the block device number and set up pointer tables */
163     int __init xd_init (void)
164     {
165     	init_timer (&xd_timer); xd_timer.function = xd_wakeup;
166     	init_timer (&xd_watchdog_int); xd_watchdog_int.function = xd_watchdog;
167     
168     	if (devfs_register_blkdev(MAJOR_NR,"xd",&xd_fops)) {
169     		printk("xd: Unable to get major number %d\n",MAJOR_NR);
170     		return -1;
171     	}
172     	devfs_handle = devfs_mk_dir (NULL, xd_gendisk.major_name, NULL);
173     	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
174     	read_ahead[MAJOR_NR] = 8;	/* 8 sector (4kB) read ahead */
175     	add_gendisk(&xd_gendisk);
176     	xd_geninit();
177     
178     	return 0;
179     }
180     
181     /* xd_detect: scan the possible BIOS ROM locations for the signature strings */
182     static u_char __init xd_detect (u_char *controller, unsigned int *address)
183     {
184     	u_char i,j,found = 0;
185     
186     	if (xd_override)
187     	{
188     		*controller = xd_type;
189     		*address = 0;
190     		return(1);
191     	}
192     
193     	for (i = 0; i < (sizeof(xd_bases) / sizeof(xd_bases[0])) && !found; i++)
194     		for (j = 1; j < (sizeof(xd_sigs) / sizeof(xd_sigs[0])) && !found; j++)
195     			if (isa_check_signature(xd_bases[i] + xd_sigs[j].offset,xd_sigs[j].string,strlen(xd_sigs[j].string))) {
196     				*controller = j;
197     				xd_type = j;
198     				*address = xd_bases[i];
199     				found++;
200     			}
201     	return (found);
202     }
203     
204     /* xd_geninit: grab the IRQ and DMA channel, initialise the drives */
205     /* and set up the "raw" device entries in the table */
206     static void __init xd_geninit (void)
207     {
208     	u_char i,controller;
209     	unsigned int address;
210     
211     	for(i=0;i<(XD_MAXDRIVES << 6);i++) xd_blocksizes[i] = 1024;
212     	blksize_size[MAJOR_NR] = xd_blocksizes;
213     
214     	if (xd_detect(&controller,&address)) {
215     
216     		printk("Detected a%s controller (type %d) at address %06x\n",
217     			xd_sigs[controller].name,controller,address);
218     		if (check_region(xd_iobase,4)) {
219     			printk("xd: Ports at 0x%x are not available\n",
220     				xd_iobase);
221     			return;
222     		}
223     		request_region(xd_iobase,4,"xd");
224     		if (controller)
225     			xd_sigs[controller].init_controller(address);
226     		xd_drives = xd_initdrives(xd_sigs[controller].init_drive);
227     		
228     		printk("Detected %d hard drive%s (using IRQ%d & DMA%d)\n",
229     			xd_drives,xd_drives == 1 ? "" : "s",xd_irq,xd_dma);
230     		for (i = 0; i < xd_drives; i++)
231     			printk(" xd%c: CHS=%d/%d/%d\n",'a'+i,
232     				xd_info[i].cylinders,xd_info[i].heads,
233     				xd_info[i].sectors);
234     
235     	}
236     	if (xd_drives) {
237     		if (!request_irq(xd_irq,xd_interrupt_handler, 0, "XT hard disk", NULL)) {
238     			if (request_dma(xd_dma,"xd")) {
239     				printk("xd: unable to get DMA%d\n",xd_dma);
240     				free_irq(xd_irq, NULL);
241     			}
242     		}
243     		else
244     			printk("xd: unable to get IRQ%d\n",xd_irq);
245     	}
246     
247     	/* xd_maxsectors depends on controller - so set after detection */
248     	for(i=0; i<(XD_MAXDRIVES << 6); i++) xd_maxsect[i] = xd_maxsectors;
249     	max_sectors[MAJOR_NR] = xd_maxsect;
250     
251     	for (i = 0; i < xd_drives; i++) {
252     		xd_valid[i] = 1;
253     		register_disk(&xd_gendisk, MKDEV(MAJOR_NR,i<<6), 1<<6, &xd_fops,
254     				xd_info[i].heads * xd_info[i].cylinders *
255     				xd_info[i].sectors);
256     	}
257     
258     	xd_gendisk.nr_real = xd_drives;
259     
260     }
261     
262     /* xd_open: open a device */
263     static int xd_open (struct inode *inode,struct file *file)
264     {
265     	int dev = DEVICE_NR(inode->i_rdev);
266     
267     	MOD_INC_USE_COUNT;
268     
269     	if (dev < xd_drives) {
270     		while (!xd_valid[dev])
271     			sleep_on(&xd_wait_open);
272     
273     		xd_access[dev]++;
274     
275     		return (0);
276     	}
277     
278     	MOD_DEC_USE_COUNT;
279     	return -ENXIO;
280     }
281     
282     /* do_xd_request: handle an incoming request */
283     static void do_xd_request (request_queue_t * q)
284     {
285     	u_int block,count,retry;
286     	int code;
287     
288     	sti();
289     	if (xdc_busy)
290     		return;
291     	while (code = 0, !QUEUE_EMPTY) {
292     		INIT_REQUEST;	/* do some checking on the request structure */
293     
294     		if (CURRENT_DEV < xd_drives
295     		    && CURRENT->sector + CURRENT->nr_sectors
296     		         <= xd_struct[MINOR(CURRENT->rq_dev)].nr_sects) {
297     			block = CURRENT->sector + xd_struct[MINOR(CURRENT->rq_dev)].start_sect;
298     			count = CURRENT->nr_sectors;
299     
300     			switch (CURRENT->cmd) {
301     				case READ:
302     				case WRITE:
303     					for (retry = 0; (retry < XD_RETRIES) && !code; retry++)
304     						code = xd_readwrite(CURRENT->cmd,CURRENT_DEV,CURRENT->buffer,block,count);
305     					break;
306     				default:
307     					printk("do_xd_request: unknown request\n");
308     					break;
309     			}
310     		}
311     		end_request(code);	/* wrap up, 0 = fail, 1 = success */
312     	}
313     }
314     
315     /* xd_ioctl: handle device ioctl's */
316     static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg)
317     {
318     	int dev;
319     
320     	if ((!inode) || !(inode->i_rdev))
321     		return -EINVAL;
322      	dev = DEVICE_NR(inode->i_rdev);
323     
324     	if (dev >= xd_drives) return -EINVAL;
325     	switch (cmd) {
326     		case HDIO_GETGEO:
327     		{
328     			struct hd_geometry g;
329     			struct hd_geometry *geometry = (struct hd_geometry *) arg;
330     			if (!geometry) return -EINVAL;
331     			g.heads = xd_info[dev].heads;
332     			g.sectors = xd_info[dev].sectors;
333     			g.cylinders = xd_info[dev].cylinders;
334     			g.start = xd_struct[MINOR(inode->i_rdev)].start_sect;
335     			return copy_to_user(geometry, &g, sizeof g) ? -EFAULT : 0;
336     		}
337     		case BLKGETSIZE:
338     			if (!arg) return -EINVAL;
339     			return put_user(xd_struct[MINOR(inode->i_rdev)].nr_sects,(long *) arg);
340     		case BLKGETSIZE64:
341     			return put_user((u64)xd_struct[MINOR(inode->i_rdev)].nr_sects << 9, (u64 *)arg);
342     		case HDIO_SET_DMA:
343     			if (!capable(CAP_SYS_ADMIN)) return -EACCES;
344     			if (xdc_busy) return -EBUSY;
345     			nodma = !arg;
346     			if (nodma && xd_dma_buffer) {
347     				xd_dma_mem_free((unsigned long)xd_dma_buffer, xd_maxsectors * 0x200);
348     				xd_dma_buffer = 0;
349     			}
350     			return 0;
351     		case HDIO_GET_DMA:
352     			return put_user(!nodma, (long *) arg);
353     		case HDIO_GET_MULTCOUNT:
354     			return put_user(xd_maxsectors, (long *) arg);
355     		case BLKRRPART:
356     			if (!capable(CAP_SYS_ADMIN)) 
357     				return -EACCES;
358     			return xd_reread_partitions(inode->i_rdev);
359     
360     		case BLKFLSBUF:
361     		case BLKROSET:
362     		case BLKROGET:
363     		case BLKRASET:
364     		case BLKRAGET:
365     		case BLKPG:
366     			return blk_ioctl(inode->i_rdev, cmd, arg);
367     
368     		default:
369     			return -EINVAL;
370     	}
371     }
372     
373     /* xd_release: release the device */
374     static int xd_release (struct inode *inode, struct file *file)
375     {
376     	int target = DEVICE_NR(inode->i_rdev);
377     	if (target < xd_drives) {
378     		xd_access[target]--;
379     		MOD_DEC_USE_COUNT;
380     	}
381     	return 0;
382     }
383     
384     /* xd_reread_partitions: rereads the partition table from a drive */
385     static int xd_reread_partitions(kdev_t dev)
386     {
387     	int target;
388     	int start;
389     	int partition;
390     	
391     	target = DEVICE_NR(dev);
392      	start = target << xd_gendisk.minor_shift;
393     
394     	cli();
395     	xd_valid[target] = (xd_access[target] != 1);
396             sti();
397     	if (xd_valid[target])
398     		return -EBUSY;
399     
400     	for (partition = xd_gendisk.max_p - 1; partition >= 0; partition--) {
401     		int minor = (start | partition);
402     		invalidate_device(MKDEV(MAJOR_NR, minor), 1);
403     		xd_gendisk.part[minor].start_sect = 0;
404     		xd_gendisk.part[minor].nr_sects = 0;
405     	};
406     
407     	grok_partitions(&xd_gendisk, target, 1<<6,
408     			xd_info[target].heads * xd_info[target].cylinders * xd_info[target].sectors);
409     
410     	xd_valid[target] = 1;
411     	wake_up(&xd_wait_open);
412     
413     	return 0;
414     }
415     
416     /* xd_readwrite: handle a read/write request */
417     static int xd_readwrite (u_char operation,u_char drive,char *buffer,u_int block,u_int count)
418     {
419     	u_char cmdblk[6],sense[4];
420     	u_short track,cylinder;
421     	u_char head,sector,control,mode = PIO_MODE,temp;
422     	char **real_buffer;
423     	register int i;
424     	
425     #ifdef DEBUG_READWRITE
426     	printk("xd_readwrite: operation = %s, drive = %d, buffer = 0x%X, block = %d, count = %d\n",operation == READ ? "read" : "write",drive,buffer,block,count);
427     #endif /* DEBUG_READWRITE */
428     
429     	control = xd_info[drive].control;
430     	if (!xd_dma_buffer)
431     		xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
432     	while (count) {
433     		temp = count < xd_maxsectors ? count : xd_maxsectors;
434     
435     		track = block / xd_info[drive].sectors;
436     		head = track % xd_info[drive].heads;
437     		cylinder = track / xd_info[drive].heads;
438     		sector = block % xd_info[drive].sectors;
439     
440     #ifdef DEBUG_READWRITE
441     		printk("xd_readwrite: drive = %d, head = %d, cylinder = %d, sector = %d, count = %d\n",drive,head,cylinder,sector,temp);
442     #endif /* DEBUG_READWRITE */
443     
444     		if (xd_dma_buffer) {
445     			mode = xd_setup_dma(operation == READ ? DMA_MODE_READ : DMA_MODE_WRITE,(u_char *)(xd_dma_buffer),temp * 0x200);
446     			real_buffer = &xd_dma_buffer;
447     			for (i=0; i < (temp * 0x200); i++)
448     				xd_dma_buffer[i] = buffer[i];
449     		}
450     		else
451     			real_buffer = &buffer;
452     
453     		xd_build(cmdblk,operation == READ ? CMD_READ : CMD_WRITE,drive,head,cylinder,sector,temp & 0xFF,control);
454     
455     		switch (xd_command(cmdblk,mode,(u_char *)(*real_buffer),(u_char *)(*real_buffer),sense,XD_TIMEOUT)) {
456     			case 1:
457     				printk("xd%c: %s timeout, recalibrating drive\n",'a'+drive,(operation == READ ? "read" : "write"));
458     				xd_recalibrate(drive);
459     				return (0);
460     			case 2:
461     				if (sense[0] & 0x30) {
462     					printk("xd%c: %s - ",'a'+drive,(operation == READ ? "reading" : "writing"));
463     					switch ((sense[0] & 0x30) >> 4) {
464     					case 0: printk("drive error, code = 0x%X",sense[0] & 0x0F);
465     						break;
466     					case 1: printk("controller error, code = 0x%X",sense[0] & 0x0F);
467     						break;
468     					case 2: printk("command error, code = 0x%X",sense[0] & 0x0F);
469     						break;
470     					case 3: printk("miscellaneous error, code = 0x%X",sense[0] & 0x0F);
471     						break;
472     					}
473     				}
474     				if (sense[0] & 0x80)
475     					printk(" - CHS = %d/%d/%d\n",((sense[2] & 0xC0) << 2) | sense[3],sense[1] & 0x1F,sense[2] & 0x3F);
476     				/*	reported drive number = (sense[1] & 0xE0) >> 5 */
477     				else
478     					printk(" - no valid disk address\n");
479     				return (0);
480     		}
481     		if (xd_dma_buffer)
482     			for (i=0; i < (temp * 0x200); i++)
483     				buffer[i] = xd_dma_buffer[i];
484     
485     		count -= temp, buffer += temp * 0x200, block += temp;
486     	}
487     	return (1);
488     }
489     
490     /* xd_recalibrate: recalibrate a given drive and reset controller if necessary */
491     static void xd_recalibrate (u_char drive)
492     {
493     	u_char cmdblk[6];
494     	
495     	xd_build(cmdblk,CMD_RECALIBRATE,drive,0,0,0,0,0);
496     	if (xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 8))
497     		printk("xd%c: warning! error recalibrating, controller may be unstable\n", 'a'+drive);
498     }
499     
500     /* xd_interrupt_handler: interrupt service routine */
501     static void xd_interrupt_handler(int irq, void *dev_id, struct pt_regs * regs)
502     {
503     	if (inb(XD_STATUS) & STAT_INTERRUPT) {							/* check if it was our device */
504     #ifdef DEBUG_OTHER
505     		printk("xd_interrupt_handler: interrupt detected\n");
506     #endif /* DEBUG_OTHER */
507     		outb(0,XD_CONTROL);								/* acknowledge interrupt */
508     		wake_up(&xd_wait_int);								/* and wake up sleeping processes */
509     	}
510     	else
511     		printk("xd: unexpected interrupt\n");
512     }
513     
514     /* xd_setup_dma: set up the DMA controller for a data transfer */
515     static u_char xd_setup_dma (u_char mode,u_char *buffer,u_int count)
516     {
517     	unsigned long f;
518     	
519     	if (nodma)
520     		return (PIO_MODE);
521     	if (((unsigned long) buffer & 0xFFFF0000) != (((unsigned long) buffer + count) & 0xFFFF0000)) {
522     #ifdef DEBUG_OTHER
523     		printk("xd_setup_dma: using PIO, transfer overlaps 64k boundary\n");
524     #endif /* DEBUG_OTHER */
525     		return (PIO_MODE);
526     	}
527     	
528     	f=claim_dma_lock();
529     	disable_dma(xd_dma);
530     	clear_dma_ff(xd_dma);
531     	set_dma_mode(xd_dma,mode);
532     	set_dma_addr(xd_dma, (unsigned long) buffer);
533     	set_dma_count(xd_dma,count);
534     	
535     	release_dma_lock(f);
536     
537     	return (DMA_MODE);			/* use DMA and INT */
538     }
539     
540     /* xd_build: put stuff into an array in a format suitable for the controller */
541     static u_char *xd_build (u_char *cmdblk,u_char command,u_char drive,u_char head,u_short cylinder,u_char sector,u_char count,u_char control)
542     {
543     	cmdblk[0] = command;
544     	cmdblk[1] = ((drive & 0x07) << 5) | (head & 0x1F);
545     	cmdblk[2] = ((cylinder & 0x300) >> 2) | (sector & 0x3F);
546     	cmdblk[3] = cylinder & 0xFF;
547     	cmdblk[4] = count;
548     	cmdblk[5] = control;
549     	
550     	return (cmdblk);
551     }
552     
553     /* xd_wakeup is called from timer interrupt */
554     static void xd_wakeup (unsigned long unused)
555     {
556     	wake_up(&xdc_wait);
557     }
558     
559     /* xd_wakeup is called from timer interrupt */
560     static void xd_watchdog (unsigned long unused)
561     {
562     	xd_error = 1;
563     	wake_up(&xd_wait_int);
564     }
565     
566     /* xd_waitport: waits until port & mask == flags or a timeout occurs. return 1 for a timeout */
567     static inline u_char xd_waitport (u_short port,u_char flags,u_char mask,u_long timeout)
568     {
569     	u_long expiry = jiffies + timeout;
570     	int success;
571     
572     	xdc_busy = 1;
573     	while ((success = ((inb(port) & mask) != flags)) && time_before(jiffies, expiry)) {
574     		xd_timer.expires = jiffies;
575     		cli();
576     		add_timer(&xd_timer);
577     		sleep_on(&xdc_wait);
578     		del_timer(&xd_timer);
579     		sti();
580     	}
581     	xdc_busy = 0;
582     	return (success);
583     }
584     
585     static inline u_int xd_wait_for_IRQ (void)
586     {
587     	unsigned long flags;
588     	xd_watchdog_int.expires = jiffies + 8 * HZ;
589     	add_timer(&xd_watchdog_int);
590     	
591     	flags=claim_dma_lock();
592     	enable_dma(xd_dma);
593     	release_dma_lock(flags);
594     	
595     	sleep_on(&xd_wait_int);
596     	del_timer(&xd_watchdog_int);
597     	xdc_busy = 0;
598     	
599     	flags=claim_dma_lock();
600     	disable_dma(xd_dma);
601     	release_dma_lock(flags);
602     	
603     	if (xd_error) {
604     		printk("xd: missed IRQ - command aborted\n");
605     		xd_error = 0;
606     		return (1);
607     	}
608     	return (0);
609     }
610     
611     /* xd_command: handle all data transfers necessary for a single command */
612     static u_int xd_command (u_char *command,u_char mode,u_char *indata,u_char *outdata,u_char *sense,u_long timeout)
613     {
614     	u_char cmdblk[6],csb,complete = 0;
615     
616     #ifdef DEBUG_COMMAND
617     	printk("xd_command: command = 0x%X, mode = 0x%X, indata = 0x%X, outdata = 0x%X, sense = 0x%X\n",command,mode,indata,outdata,sense);
618     #endif /* DEBUG_COMMAND */
619     
620     	outb(0,XD_SELECT);
621     	outb(mode,XD_CONTROL);
622     
623     	if (xd_waitport(XD_STATUS,STAT_SELECT,STAT_SELECT,timeout))
624     		return (1);
625     
626     	while (!complete) {
627     		if (xd_waitport(XD_STATUS,STAT_READY,STAT_READY,timeout))
628     			return (1);
629     
630     		switch (inb(XD_STATUS) & (STAT_COMMAND | STAT_INPUT)) {
631     			case 0:
632     				if (mode == DMA_MODE) {
633     					if (xd_wait_for_IRQ())
634     						return (1);
635     				} else
636     					outb(outdata ? *outdata++ : 0,XD_DATA);
637     				break;
638     			case STAT_INPUT:
639     				if (mode == DMA_MODE) {
640     					if (xd_wait_for_IRQ())
641     						return (1);
642     				} else
643     					if (indata)
644     						*indata++ = inb(XD_DATA);
645     					else
646     						inb(XD_DATA);
647     				break;
648     			case STAT_COMMAND:
649     				outb(command ? *command++ : 0,XD_DATA);
650     				break;
651     			case STAT_COMMAND | STAT_INPUT:
652     				complete = 1;
653     				break;
654     		}
655     	}
656     	csb = inb(XD_DATA);
657     
658     	if (xd_waitport(XD_STATUS,0,STAT_SELECT,timeout))					/* wait until deselected */
659     		return (1);
660     
661     	if (csb & CSB_ERROR) {									/* read sense data if error */
662     		xd_build(cmdblk,CMD_SENSE,(csb & CSB_LUN) >> 5,0,0,0,0,0);
663     		if (xd_command(cmdblk,0,sense,0,0,XD_TIMEOUT))
664     			printk("xd: warning! sense command failed!\n");
665     	}
666     
667     #ifdef DEBUG_COMMAND
668     	printk("xd_command: completed with csb = 0x%X\n",csb);
669     #endif /* DEBUG_COMMAND */
670     
671     	return (csb & CSB_ERROR);
672     }
673     
674     static u_char __init xd_initdrives (void (*init_drive)(u_char drive))
675     {
676     	u_char cmdblk[6],i,count = 0;
677     
678     	for (i = 0; i < XD_MAXDRIVES; i++) {
679     		xd_build(cmdblk,CMD_TESTREADY,i,0,0,0,0,0);
680     		if (!xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 8)) {
681     	 		xd_timer.expires = jiffies + XD_INIT_DISK_DELAY;
682     			add_timer(&xd_timer);
683     			sleep_on(&xdc_wait);
684     
685     			init_drive(count);
686     			count++;
687     
688     	 		xd_timer.expires = jiffies + XD_INIT_DISK_DELAY;
689     			add_timer(&xd_timer);
690     			sleep_on(&xdc_wait);
691     		}
692     	}
693     	return (count);
694     }
695     
696     static void __init xd_manual_geo_set (u_char drive)
697     {
698     	xd_info[drive].heads = (u_char)(xd_geo[3 * drive + 1]);
699     	xd_info[drive].cylinders = (u_short)(xd_geo[3 * drive]);
700     	xd_info[drive].sectors = (u_char)(xd_geo[3 * drive + 2]);
701     }
702     
703     static void __init xd_dtc_init_controller (unsigned int address)
704     {
705     	switch (address) {
706     		case 0x00000:
707     		case 0xC8000:	break;			/*initial: 0x320 */
708     		case 0xCA000:	xd_iobase = 0x324; 
709     		case 0xD0000:				/*5150CX*/
710     		case 0xD8000:	break;			/*5150CX & 5150XL*/
711     		default:        printk("xd_dtc_init_controller: unsupported BIOS address %06x\n",address);
712     				break;
713     	}
714     	xd_maxsectors = 0x01;		/* my card seems to have trouble doing multi-block transfers? */
715     
716     	outb(0,XD_RESET);		/* reset the controller */
717     }
718     
719     
720     static void __init xd_dtc5150cx_init_drive (u_char drive)
721     {
722     	/* values from controller's BIOS - BIOS chip may be removed */
723     	static u_short geometry_table[][4] = {
724     		{0x200,8,0x200,0x100},
725     		{0x267,2,0x267,0x267},
726     		{0x264,4,0x264,0x80},
727     		{0x132,4,0x132,0x0},
728     		{0x132,2,0x80, 0x132},
729     		{0x177,8,0x177,0x0},
730     		{0x132,8,0x84, 0x0},
731     		{},  /* not used */
732     		{0x132,6,0x80, 0x100},
733     		{0x200,6,0x100,0x100},
734     		{0x264,2,0x264,0x80},
735     		{0x280,4,0x280,0x100},
736     		{0x2B9,3,0x2B9,0x2B9},
737     		{0x2B9,5,0x2B9,0x2B9},
738     		{0x280,6,0x280,0x100},
739     		{0x132,4,0x132,0x0}};
740     	u_char n;
741     
742     	n = inb(XD_JUMPER);
743     	n = (drive ? n : (n >> 2)) & 0x33;
744     	n = (n | (n >> 2)) & 0x0F;
745     	if (xd_geo[3*drive])
746     		xd_manual_geo_set(drive);
747     	else
748     		if (n != 7) {	
749     			xd_info[drive].heads = (u_char)(geometry_table[n][1]);			/* heads */
750     			xd_info[drive].cylinders = geometry_table[n][0];	/* cylinders */
751     			xd_info[drive].sectors = 17;				/* sectors */
752     #if 0
753     			xd_info[drive].rwrite = geometry_table[n][2];	/* reduced write */
754     			xd_info[drive].precomp = geometry_table[n][3]		/* write precomp */
755     			xd_info[drive].ecc = 0x0B;				/* ecc length */
756     #endif /* 0 */
757     		}
758     		else {
759     			printk("xd%c: undetermined drive geometry\n",'a'+drive);
760     			return;
761     		}
762     	xd_info[drive].control = 5;				/* control byte */
763     	xd_setparam(CMD_DTCSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,geometry_table[n][2],geometry_table[n][3],0x0B);
764     	xd_recalibrate(drive);
765     }
766     
767     static void __init xd_dtc_init_drive (u_char drive)
768     {
769     	u_char cmdblk[6],buf[64];
770     
771     	xd_build(cmdblk,CMD_DTCGETGEOM,drive,0,0,0,0,0);
772     	if (!xd_command(cmdblk,PIO_MODE,buf,0,0,XD_TIMEOUT * 2)) {
773     		xd_info[drive].heads = buf[0x0A];			/* heads */
774     		xd_info[drive].cylinders = ((u_short *) (buf))[0x04];	/* cylinders */
775     		xd_info[drive].sectors = 17;				/* sectors */
776     		if (xd_geo[3*drive])
777     			xd_manual_geo_set(drive);
778     #if 0
779     		xd_info[drive].rwrite = ((u_short *) (buf + 1))[0x05];	/* reduced write */
780     		xd_info[drive].precomp = ((u_short *) (buf + 1))[0x06];	/* write precomp */
781     		xd_info[drive].ecc = buf[0x0F];				/* ecc length */
782     #endif /* 0 */
783     		xd_info[drive].control = 0;				/* control byte */
784     
785     		xd_setparam(CMD_DTCSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,((u_short *) (buf + 1))[0x05],((u_short *) (buf + 1))[0x06],buf[0x0F]);
786     		xd_build(cmdblk,CMD_DTCSETSTEP,drive,0,0,0,0,7);
787     		if (xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 2))
788     			printk("xd_dtc_init_drive: error setting step rate for xd%c\n", 'a'+drive);
789     	}
790     	else
791     		printk("xd_dtc_init_drive: error reading geometry for xd%c\n", 'a'+drive);
792     }
793     
794     static void __init xd_wd_init_controller (unsigned int address)
795     {
796     	switch (address) {
797     		case 0x00000:
798     		case 0xC8000:	break;			/*initial: 0x320 */
799     		case 0xCA000:	xd_iobase = 0x324; break;
800     		case 0xCC000:   xd_iobase = 0x328; break;
801     		case 0xCE000:   xd_iobase = 0x32C; break;
802     		case 0xD0000:	xd_iobase = 0x328; break; /* ? */
803     		case 0xD8000:	xd_iobase = 0x32C; break; /* ? */
804     		default:        printk("xd_wd_init_controller: unsupported BIOS address %06x\n",address);
805     				break;
806     	}
807     	xd_maxsectors = 0x01;		/* this one doesn't wrap properly either... */
808     
809     	outb(0,XD_RESET);		/* reset the controller */
810     
811     	xd_timer.expires = jiffies + XD_INIT_DISK_DELAY;
812     	add_timer(&xd_timer);
813     	sleep_on(&xdc_wait);
814     }
815     
816     static void __init xd_wd_init_drive (u_char drive)
817     {
818     	/* values from controller's BIOS - BIOS may be disabled */
819     	static u_short geometry_table[][4] = {
820     		{0x264,4,0x1C2,0x1C2},   /* common part */
821     		{0x132,4,0x099,0x0},
822     		{0x267,2,0x1C2,0x1C2},
823     		{0x267,4,0x1C2,0x1C2},
824     
825     		{0x334,6,0x335,0x335},   /* 1004 series RLL */
826     		{0x30E,4,0x30F,0x3DC},
827     		{0x30E,2,0x30F,0x30F},
828     		{0x267,4,0x268,0x268},
829     
830     		{0x3D5,5,0x3D6,0x3D6},   /* 1002 series RLL */
831     		{0x3DB,7,0x3DC,0x3DC},
832     		{0x264,4,0x265,0x265},
833     		{0x267,4,0x268,0x268}};
834     
835     	u_char cmdblk[6],buf[0x200];
836     	u_char n = 0,rll,jumper_state,use_jumper_geo;
837     	u_char wd_1002 = (xd_sigs[xd_type].string[7] == '6');
838     	
839     	jumper_state = ~(inb(0x322));
840     	if (jumper_state & 0x40)
841     		xd_irq = 9;
842     	rll = (jumper_state & 0x30) ? (0x04 << wd_1002) : 0;
843     	xd_build(cmdblk,CMD_READ,drive,0,0,0,1,0);
844     	if (!xd_command(cmdblk,PIO_MODE,buf,0,0,XD_TIMEOUT * 2)) {
845     		xd_info[drive].heads = buf[0x1AF];				/* heads */
846     		xd_info[drive].cylinders = ((u_short *) (buf + 1))[0xD6];	/* cylinders */
847     		xd_info[drive].sectors = 17;					/* sectors */
848     		if (xd_geo[3*drive])
849     			xd_manual_geo_set(drive);
850     #if 0
851     		xd_info[drive].rwrite = ((u_short *) (buf))[0xD8];		/* reduced write */
852     		xd_info[drive].wprecomp = ((u_short *) (buf))[0xDA];		/* write precomp */
853     		xd_info[drive].ecc = buf[0x1B4];				/* ecc length */
854     #endif /* 0 */
855     		xd_info[drive].control = buf[0x1B5];				/* control byte */
856     		use_jumper_geo = !(xd_info[drive].heads) || !(xd_info[drive].cylinders);
857     		if (xd_geo[3*drive]) {
858     			xd_manual_geo_set(drive);
859     			xd_info[drive].control = rll ? 7 : 5;
860     		}
861     		else if (use_jumper_geo) {
862     			n = (((jumper_state & 0x0F) >> (drive << 1)) & 0x03) | rll;
863     			xd_info[drive].cylinders = geometry_table[n][0];
864     			xd_info[drive].heads = (u_char)(geometry_table[n][1]);
865     			xd_info[drive].control = rll ? 7 : 5;
866     #if 0
867     			xd_info[drive].rwrite = geometry_table[n][2];
868     			xd_info[drive].wprecomp = geometry_table[n][3];
869     			xd_info[drive].ecc = 0x0B;
870     #endif /* 0 */
871     		}
872     		if (!wd_1002) {
873     			if (use_jumper_geo)
874     				xd_setparam(CMD_WDSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,
875     					geometry_table[n][2],geometry_table[n][3],0x0B);
876     			else
877     				xd_setparam(CMD_WDSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,
878     					((u_short *) (buf))[0xD8],((u_short *) (buf))[0xDA],buf[0x1B4]);
879     		}
880     	/* 1002 based RLL controller requests converted addressing, but reports physical 
881     	   (physical 26 sec., logical 17 sec.) 
882     	   1004 based ???? */
883     		if (rll & wd_1002) {
884     			if ((xd_info[drive].cylinders *= 26,
885     			     xd_info[drive].cylinders /= 17) > 1023)
886     				xd_info[drive].cylinders = 1023;  /* 1024 ? */
887     #if 0
888     			xd_info[drive].rwrite *= 26; 
889     			xd_info[drive].rwrite /= 17;
890     			xd_info[drive].wprecomp *= 26
891     			xd_info[drive].wprecomp /= 17;
892     #endif /* 0 */
893     		}
894     	}
895     	else
896     		printk("xd_wd_init_drive: error reading geometry for xd%c\n",'a'+drive);	
897     
898     }
899     
900     static void __init xd_seagate_init_controller (unsigned int address)
901     {
902     	switch (address) {
903     		case 0x00000:
904     		case 0xC8000:	break;			/*initial: 0x320 */
905     		case 0xD0000:	xd_iobase = 0x324; break;
906     		case 0xD8000:	xd_iobase = 0x328; break;
907     		case 0xE0000:	xd_iobase = 0x32C; break;
908     		default:	printk("xd_seagate_init_controller: unsupported BIOS address %06x\n",address);
909     				break;
910     	}
911     	xd_maxsectors = 0x40;
912     
913     	outb(0,XD_RESET);		/* reset the controller */
914     }
915     
916     static void __init xd_seagate_init_drive (u_char drive)
917     {
918     	u_char cmdblk[6],buf[0x200];
919     
920     	xd_build(cmdblk,CMD_ST11GETGEOM,drive,0,0,0,1,0);
921     	if (!xd_command(cmdblk,PIO_MODE,buf,0,0,XD_TIMEOUT * 2)) {
922     		xd_info[drive].heads = buf[0x04];				/* heads */
923     		xd_info[drive].cylinders = (buf[0x02] << 8) | buf[0x03];	/* cylinders */
924     		xd_info[drive].sectors = buf[0x05];				/* sectors */
925     		xd_info[drive].control = 0;					/* control byte */
926     	}
927     	else
928     		printk("xd_seagate_init_drive: error reading geometry from xd%c\n", 'a'+drive);
929     }
930     
931     /* Omti support courtesy Dirk Melchers */
932     static void __init xd_omti_init_controller (unsigned int address)
933     {
934     	switch (address) {
935     		case 0x00000:
936     		case 0xC8000:	break;			/*initial: 0x320 */
937     		case 0xD0000:	xd_iobase = 0x324; break;
938     		case 0xD8000:	xd_iobase = 0x328; break;
939     		case 0xE0000:	xd_iobase = 0x32C; break;
940     		default:	printk("xd_omti_init_controller: unsupported BIOS address %06x\n",address);
941     				break;
942     	}
943     	
944     	xd_maxsectors = 0x40;
945     
946     	outb(0,XD_RESET);		/* reset the controller */
947     }
948     
949     static void __init xd_omti_init_drive (u_char drive)
950     {
951     	/* gets infos from drive */
952     	xd_override_init_drive(drive);
953     
954     	/* set other parameters, Hardcoded, not that nice :-) */
955     	xd_info[drive].control = 2;
956     }
957     
958     /* Xebec support (AK) */
959     static void __init xd_xebec_init_controller (unsigned int address)
960     {
961     /* iobase may be set manually in range 0x300 - 0x33C
962           irq may be set manually to 2(9),3,4,5,6,7
963           dma may be set manually to 1,2,3
964     	(How to detect them ???)
965     BIOS address may be set manually in range 0x0 - 0xF8000
966     If you need non-standard settings use the xd=... command */
967     
968     	switch (address) {
969     		case 0x00000:
970     		case 0xC8000:	/* initially: xd_iobase==0x320 */
971     		case 0xD0000:
972     		case 0xD2000:
973     		case 0xD4000:
974     		case 0xD6000:
975     		case 0xD8000:
976     		case 0xDA000:
977     		case 0xDC000:
978     		case 0xDE000:
979     		case 0xE0000:	break;
980     		default:	printk("xd_xebec_init_controller: unsupported BIOS address %06x\n",address);
981     				break;
982     		}
983     
984     	xd_maxsectors = 0x01;
985     	outb(0,XD_RESET);		/* reset the controller */
986     
987     	xd_timer.expires = jiffies + XD_INIT_DISK_DELAY;
988     	add_timer(&xd_timer);
989     	sleep_on(&xdc_wait);
990     }
991     
992     static void __init xd_xebec_init_drive (u_char drive)
993     {
994     	/* values from controller's BIOS - BIOS chip may be removed */
995     	static u_short geometry_table[][5] = {
996     		{0x132,4,0x080,0x080,0x7},
997     		{0x132,4,0x080,0x080,0x17},
998     		{0x264,2,0x100,0x100,0x7},
999     		{0x264,2,0x100,0x100,0x17},
1000     		{0x132,8,0x080,0x080,0x7},
1001     		{0x132,8,0x080,0x080,0x17},
1002     		{0x264,4,0x100,0x100,0x6},
1003     		{0x264,4,0x100,0x100,0x17},
1004     		{0x2BC,5,0x2BC,0x12C,0x6},
1005     		{0x3A5,4,0x3A5,0x3A5,0x7},
1006     		{0x26C,6,0x26C,0x26C,0x7},
1007     		{0x200,8,0x200,0x100,0x17},
1008     		{0x400,5,0x400,0x400,0x7},
1009     		{0x400,6,0x400,0x400,0x7},
1010     		{0x264,8,0x264,0x200,0x17},
1011     		{0x33E,7,0x33E,0x200,0x7}};
1012     	u_char n;
1013     
1014     	n = inb(XD_JUMPER) & 0x0F; /* BIOS's drive number: same geometry 
1015     					is assumed for BOTH drives */
1016     	if (xd_geo[3*drive])
1017     		xd_manual_geo_set(drive);
1018     	else {
1019     		xd_info[drive].heads = (u_char)(geometry_table[n][1]);			/* heads */
1020     		xd_info[drive].cylinders = geometry_table[n][0];	/* cylinders */
1021     		xd_info[drive].sectors = 17;				/* sectors */
1022     #if 0
1023     		xd_info[drive].rwrite = geometry_table[n][2];	/* reduced write */
1024     		xd_info[drive].precomp = geometry_table[n][3]		/* write precomp */
1025     		xd_info[drive].ecc = 0x0B;				/* ecc length */
1026     #endif /* 0 */
1027     	}
1028     	xd_info[drive].control = geometry_table[n][4];			/* control byte */
1029     	xd_setparam(CMD_XBSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,geometry_table[n][2],geometry_table[n][3],0x0B);
1030     	xd_recalibrate(drive);
1031     }
1032     
1033     /* xd_override_init_drive: this finds disk geometry in a "binary search" style, narrowing in on the "correct" number of heads
1034        etc. by trying values until it gets the highest successful value. Idea courtesy Salvador Abreu (spa@fct.unl.pt). */
1035     static void __init xd_override_init_drive (u_char drive)
1036     {
1037     	u_short min[] = { 0,0,0 },max[] = { 16,1024,64 },test[] = { 0,0,0 };
1038     	u_char cmdblk[6],i;
1039     
1040     	if (xd_geo[3*drive])
1041     		xd_manual_geo_set(drive);
1042     	else {
1043     		for (i = 0; i < 3; i++) {
1044     			while (min[i] != max[i] - 1) {
1045     				test[i] = (min[i] + max[i]) / 2;
1046     				xd_build(cmdblk,CMD_SEEK,drive,(u_char) test[0],(u_short) test[1],(u_char) test[2],0,0);
1047     				if (!xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 2))
1048     					min[i] = test[i];
1049     				else
1050     					max[i] = test[i];
1051     			}
1052     			test[i] = min[i];
1053     		}
1054     		xd_info[drive].heads = (u_char) min[0] + 1;
1055     		xd_info[drive].cylinders = (u_short) min[1] + 1;
1056     		xd_info[drive].sectors = (u_char) min[2] + 1;
1057     	}
1058     	xd_info[drive].control = 0;
1059     }
1060     
1061     /* xd_setup: initialise controller from command line parameters */
1062     void __init do_xd_setup (int *integers)
1063     {
1064     	switch (integers[0]) {
1065     		case 4: if (integers[4] < 0)
1066     				nodma = 1;
1067     			else if (integers[4] < 8)
1068     				xd_dma = integers[4];
1069     		case 3: if ((integers[3] > 0) && (integers[3] <= 0x3FC))
1070     				xd_iobase = integers[3];
1071     		case 2: if ((integers[2] > 0) && (integers[2] < 16))
1072     				xd_irq = integers[2];
1073     		case 1: xd_override = 1;
1074     			if ((integers[1] >= 0) && (integers[1] < (sizeof(xd_sigs) / sizeof(xd_sigs[0]))))
1075     				xd_type = integers[1];
1076     		case 0: break;
1077     		default:printk("xd: too many parameters for xd\n");
1078     	}
1079     	xd_maxsectors = 0x01;
1080     }
1081     
1082     /* xd_setparam: set the drive characteristics */
1083     static void __init xd_setparam (u_char command,u_char drive,u_char heads,u_short cylinders,u_short rwrite,u_short wprecomp,u_char ecc)
1084     {
1085     	u_char cmdblk[14];
1086     
1087     	xd_build(cmdblk,command,drive,0,0,0,0,0);
1088     	cmdblk[6] = (u_char) (cylinders >> 8) & 0x03;
1089     	cmdblk[7] = (u_char) (cylinders & 0xFF);
1090     	cmdblk[8] = heads & 0x1F;
1091     	cmdblk[9] = (u_char) (rwrite >> 8) & 0x03;
1092     	cmdblk[10] = (u_char) (rwrite & 0xFF);
1093     	cmdblk[11] = (u_char) (wprecomp >> 8) & 0x03;
1094     	cmdblk[12] = (u_char) (wprecomp & 0xFF);
1095     	cmdblk[13] = ecc;
1096     
1097     	/* Some controllers require geometry info as data, not command */
1098     
1099     	if (xd_command(cmdblk,PIO_MODE,0,&cmdblk[6],0,XD_TIMEOUT * 2))
1100     		printk("xd: error setting characteristics for xd%c\n", 'a'+drive);
1101     }
1102     
1103     
1104     #ifdef MODULE
1105     static int xd[5] = { -1,-1,-1,-1, };
1106     
1107     MODULE_PARM(xd, "1-4i");
1108     MODULE_PARM(xd_geo, "3-6i");
1109     MODULE_PARM(nodma, "i");
1110     
1111     MODULE_LICENSE("GPL");
1112     
1113     static void xd_done (void)
1114     {
1115     	blksize_size[MAJOR_NR] = NULL;
1116     	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
1117     	blk_size[MAJOR_NR] = NULL;
1118     	hardsect_size[MAJOR_NR] = NULL;
1119     	read_ahead[MAJOR_NR] = 0;
1120     	del_gendisk(&xd_gendisk);
1121     	release_region(xd_iobase,4);
1122     }
1123     
1124     int init_module(void)
1125     {
1126     	int i,count = 0;
1127     	int error;
1128     
1129     	for (i = 4; i > 0; i--)
1130     		if(((xd[i] = xd[i-1]) >= 0) && !count)
1131     			count = i;
1132     	if((xd[0] = count))
1133     		do_xd_setup(xd);
1134     
1135     	error = xd_init();
1136     	if (error) return error;
1137     
1138     	printk(KERN_INFO "XD: Loaded as a module.\n");
1139     	if (!xd_drives) {
1140     		/* no drives detected - unload module */
1141     		devfs_unregister_blkdev(MAJOR_NR, "xd");
1142     		xd_done();
1143     		return (-1);
1144     	}
1145             
1146     	return 0;
1147     }
1148     
1149     void cleanup_module(void)
1150     {
1151     	devfs_unregister_blkdev(MAJOR_NR, "xd");
1152     	xd_done();
1153     	devfs_unregister (devfs_handle);
1154     	if (xd_drives) {
1155     		free_irq(xd_irq, NULL);
1156     		free_dma(xd_dma);
1157     		if (xd_dma_buffer)
1158     			xd_dma_mem_free((unsigned long)xd_dma_buffer, xd_maxsectors * 0x200);
1159     	}
1160     }
1161     #else
1162     
1163     static int __init xd_setup (char *str)
1164     {
1165     	int ints[5];
1166     	get_options (str, ARRAY_SIZE (ints), ints);
1167     	do_xd_setup (ints);
1168     	return 1;
1169     }
1170     
1171     /* xd_manual_geo_init: initialise drive geometry from command line parameters
1172        (used only for WD drives) */
1173     static int __init xd_manual_geo_init (char *str)
1174     {
1175     	int i, integers[1 + 3*XD_MAXDRIVES];
1176     
1177     	get_options (str, ARRAY_SIZE (integers), integers);
1178     	if (integers[0]%3 != 0) {
1179     		printk("xd: incorrect number of parameters for xd_geo\n");
1180     		return 1;
1181     	}
1182     	for (i = 0; (i < integers[0]) && (i < 3*XD_MAXDRIVES); i++)
1183     		xd_geo[i] = integers[i+1];
1184     	return 1;
1185     }
1186     
1187     __setup ("xd=", xd_setup);
1188     __setup ("xd_geo=", xd_manual_geo_init);
1189     
1190     #endif /* MODULE */
1191     
1192