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 	{ 0x0008,"(C) Copyright 1984 Western Digital Corp", xd_wd_init_controller, xd_wd_init_drive," Western Dig. 1002s-wx2" },
111 	{ 0x0008,"(C) Copyright 1986 Western Digital Corporation", xd_wd_init_controller, xd_wd_init_drive," 1986 Western Digital" }, /* jfree@sovereign.org */
112 };
113 
114 static unsigned int xd_bases[] __initdata =
115 {
116 	0xC8000, 0xCA000, 0xCC000,
117 	0xCE000, 0xD0000, 0xD2000,
118 	0xD4000, 0xD6000, 0xD8000,
119 	0xDA000, 0xDC000, 0xDE000,
120 	0xE0000
121 };
122 
123 static struct hd_struct xd_struct[XD_MAXDRIVES << 6];
124 static int xd_sizes[XD_MAXDRIVES << 6], xd_access[XD_MAXDRIVES];
125 static int xd_blocksizes[XD_MAXDRIVES << 6];
126 static int xd_maxsect[XD_MAXDRIVES << 6];
127 
128 static struct block_device_operations xd_fops = {
129 	owner:		THIS_MODULE,
130 	open:		xd_open,
131 	release:	xd_release,
132 	ioctl:		xd_ioctl,
133 };
134 
135 static struct gendisk xd_gendisk = {
136 	major:		MAJOR_NR,
137 	major_name:	"xd",
138 	minor_shift:	6,
139 	max_p:		1 << 6,
140 	part:		xd_struct,
141 	sizes:		xd_sizes,
142 	real_devices:	(void *)xd_info,
143 	fops:		&xd_fops,
144 };
145 
146 static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int);
147 static DECLARE_WAIT_QUEUE_HEAD(xd_wait_open);
148 static u8 xd_valid[XD_MAXDRIVES] = { 0,0 };
149 static u8 xd_drives, xd_irq = 5, xd_dma = 3, xd_maxsectors;
150 static u8 xd_override __initdata = 0, xd_type __initdata = 0;
151 static u16 xd_iobase = 0x320;
152 static int xd_geo[XD_MAXDRIVES*3] __initdata = { 0, };
153 
154 static volatile int xdc_busy;
155 
156 static struct timer_list xd_watchdog_int;
157 
158 static volatile u8 xd_error;
159 static int nodma = XD_DONT_USE_DMA;
160 
161 static devfs_handle_t devfs_handle = NULL;
162 
163 /* xd_init: register the block device number and set up pointer tables */
xd_init(void)164 int __init xd_init(void)
165 {
166 	init_timer (&xd_watchdog_int);
167 	xd_watchdog_int.function = xd_watchdog;
168 
169 	if (!xd_dma_buffer)
170 		xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
171 	if (!xd_dma_buffer)
172 	{
173 		printk(KERN_ERR "xd: Out of memory.\n");
174 		return -ENOMEM;
175 	}
176 
177 	if (devfs_register_blkdev(MAJOR_NR,"xd",&xd_fops)) {
178 		printk(KERN_ERR "xd: Unable to get major number %d\n",MAJOR_NR);
179 		return -1;
180 	}
181 	devfs_handle = devfs_mk_dir (NULL, xd_gendisk.major_name, NULL);
182 	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
183 	read_ahead[MAJOR_NR] = 8;	/* 8 sector (4kB) read ahead */
184 	add_gendisk(&xd_gendisk);
185 	xd_geninit();
186 
187 	return 0;
188 }
189 
190 /* xd_detect: scan the possible BIOS ROM locations for the signature strings */
191 
xd_detect(u8 * controller,unsigned int * address)192 static u8 __init xd_detect (u8 *controller, unsigned int *address)
193 {
194 	u8 i,j,found = 0;
195 
196 	if (xd_override)
197 	{
198 		*controller = xd_type;
199 		*address = 0;
200 		return(1);
201 	}
202 
203 	for (i = 0; i < (sizeof(xd_bases) / sizeof(xd_bases[0])) && !found; i++)
204 		for (j = 1; j < (sizeof(xd_sigs) / sizeof(xd_sigs[0])) && !found; j++)
205 			if (isa_check_signature(xd_bases[i] + xd_sigs[j].offset,xd_sigs[j].string,strlen(xd_sigs[j].string))) {
206 				*controller = j;
207 				xd_type = j;
208 				*address = xd_bases[i];
209 				found++;
210 			}
211 	return (found);
212 }
213 
214 /* xd_geninit: grab the IRQ and DMA channel, initialise the drives */
215 /* and set up the "raw" device entries in the table */
216 
xd_geninit(void)217 static void __init xd_geninit (void)
218 {
219 	u8 i,controller;
220 	unsigned int address;
221 
222 	for(i=0;i<(XD_MAXDRIVES << 6);i++)
223 		xd_blocksizes[i] = 1024;
224 
225 	blksize_size[MAJOR_NR] = xd_blocksizes;
226 
227 	if (xd_detect(&controller,&address)) {
228 		printk(KERN_INFO "Detected a%s controller (type %d) at address %06x\n",
229 			xd_sigs[controller].name,controller,address);
230 		if (!request_region(xd_iobase,4, "xd")) {
231 			printk(KERN_ERR "xd: Ports at 0x%x are not available\n", xd_iobase);
232 			return;
233 		}
234 		if (controller)
235 			xd_sigs[controller].init_controller(address);
236 		xd_drives = xd_initdrives(xd_sigs[controller].init_drive);
237 
238 		printk(KERN_INFO "Detected %d hard drive%s (using IRQ%d & DMA%d)\n",
239 			xd_drives,xd_drives == 1 ? "" : "s",xd_irq,xd_dma);
240 		for (i = 0; i < xd_drives; i++)
241 			printk(KERN_INFO " xd%c: CHS=%d/%d/%d\n",'a'+i,
242 				xd_info[i].cylinders,xd_info[i].heads,
243 				xd_info[i].sectors);
244 
245 	}
246 	if (xd_drives) {
247 		if (!request_irq(xd_irq,xd_interrupt_handler, 0, "XT hard disk", NULL)) {
248 			if (request_dma(xd_dma,"xd")) {
249 				printk(KERN_ERR "xd: unable to get DMA%d\n",xd_dma);
250 				free_irq(xd_irq, NULL);
251 			}
252 		}
253 		else
254 			printk(KERN_ERR "xd: unable to get IRQ%d\n",xd_irq);
255 	}
256 
257 	/* xd_maxsectors depends on controller - so set after detection */
258 	for(i=0; i<(XD_MAXDRIVES << 6); i++) xd_maxsect[i] = xd_maxsectors;
259 	max_sectors[MAJOR_NR] = xd_maxsect;
260 
261 	for (i = 0; i < xd_drives; i++) {
262 		xd_valid[i] = 1;
263 		register_disk(&xd_gendisk, MKDEV(MAJOR_NR,i<<6), 1<<6, &xd_fops,
264 				xd_info[i].heads * xd_info[i].cylinders *
265 				xd_info[i].sectors);
266 	}
267 
268 	xd_gendisk.nr_real = xd_drives;
269 
270 }
271 
272 /* xd_open: open a device */
xd_open(struct inode * inode,struct file * file)273 static int xd_open (struct inode *inode,struct file *file)
274 {
275 	int dev = DEVICE_NR(inode->i_rdev);
276 
277 	if (dev < xd_drives) {
278 		while (!xd_valid[dev])
279 			sleep_on(&xd_wait_open);
280 		xd_access[dev]++;
281 		return (0);
282 	}
283 
284 	return -ENXIO;
285 }
286 
287 /* do_xd_request: handle an incoming request */
do_xd_request(request_queue_t * q)288 static void do_xd_request (request_queue_t * q)
289 {
290 	unsigned int block,count,retry;
291 	int code;
292 
293 	if (xdc_busy)
294 		return;
295 
296 	while (code = 0, !QUEUE_EMPTY) {
297 		INIT_REQUEST;	/* do some checking on the request structure */
298 
299 		if (CURRENT_DEV < xd_drives && CURRENT->sector + CURRENT->nr_sectors <= xd_struct[MINOR(CURRENT->rq_dev)].nr_sects) {
300 			block = CURRENT->sector + xd_struct[MINOR(CURRENT->rq_dev)].start_sect;
301 			count = CURRENT->nr_sectors;
302 
303 			switch (CURRENT->cmd) {
304 				case READ:
305 				case WRITE:
306 					for (retry = 0; (retry < XD_RETRIES) && !code; retry++)
307 						code = xd_readwrite(CURRENT->cmd,CURRENT_DEV,CURRENT->buffer,block,count);
308 					break;
309 				default:
310 					BUG();
311 			}
312 		}
313 		end_request(code);	/* wrap up, 0 = fail, 1 = success */
314 	}
315 }
316 
317 /* xd_ioctl: handle device ioctl's */
318 
xd_ioctl(struct inode * inode,struct file * file,unsigned int cmd,unsigned long arg)319 static int xd_ioctl (struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg)
320 {
321 	int dev;
322 
323 	if ((!inode) || !(inode->i_rdev))
324 		return -EINVAL;
325  	dev = DEVICE_NR(inode->i_rdev);
326 
327 	if (dev >= xd_drives) return -EINVAL;
328 	switch (cmd) {
329 		case HDIO_GETGEO:
330 		{
331 			struct hd_geometry g;
332 			struct hd_geometry *geometry = (struct hd_geometry *) arg;
333 			g.heads = xd_info[dev].heads;
334 			g.sectors = xd_info[dev].sectors;
335 			g.cylinders = xd_info[dev].cylinders;
336 			g.start = xd_struct[MINOR(inode->i_rdev)].start_sect;
337 			return copy_to_user(geometry, &g, sizeof g) ? -EFAULT : 0;
338 		}
339 		case HDIO_SET_DMA:
340 			if (!capable(CAP_SYS_ADMIN))
341 				return -EACCES;
342 			if (xdc_busy)
343 				return -EBUSY;
344 
345 			nodma = !arg;
346 
347 			if (nodma && xd_dma_buffer) {
348 				xd_dma_mem_free((unsigned long)xd_dma_buffer, xd_maxsectors * 0x200);
349 				xd_dma_buffer = 0;
350 			} else if (!nodma && !xd_dma_buffer) {
351 				xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
352 				if (!xd_dma_buffer)
353 				{
354 					nodma = XD_DONT_USE_DMA;
355 					return -ENOMEM;
356 				}
357 			}
358 			return 0;
359 		case HDIO_GET_DMA:
360 			return put_user(!nodma, (long *) arg);
361 		case HDIO_GET_MULTCOUNT:
362 			return put_user(xd_maxsectors, (long *) arg);
363 		case BLKRRPART:
364 			if (!capable(CAP_SYS_ADMIN))
365 				return -EACCES;
366 			return xd_reread_partitions(inode->i_rdev);
367 		case BLKGETSIZE:
368 		case BLKGETSIZE64:
369 		case BLKFLSBUF:
370 		case BLKROSET:
371 		case BLKROGET:
372 		case BLKRASET:
373 		case BLKRAGET:
374 		case BLKPG:
375 			return blk_ioctl(inode->i_rdev, cmd, arg);
376 		default:
377 			return -EINVAL;
378 	}
379 }
380 
381 /* xd_release: release the device */
xd_release(struct inode * inode,struct file * file)382 static int xd_release (struct inode *inode, struct file *file)
383 {
384 	int target = DEVICE_NR(inode->i_rdev);
385 	if (target < xd_drives)
386 		xd_access[target]--;
387 	return 0;
388 }
389 
390 /* xd_reread_partitions: rereads the partition table from a drive */
xd_reread_partitions(kdev_t dev)391 static int xd_reread_partitions(kdev_t dev)
392 {
393 	int target;
394 	int start;
395 	int partition;
396 
397 	target = DEVICE_NR(dev);
398  	start = target << xd_gendisk.minor_shift;
399 
400 	cli();
401 	xd_valid[target] = (xd_access[target] != 1);
402         sti();
403 	if (xd_valid[target])
404 		return -EBUSY;
405 
406 	for (partition = xd_gendisk.max_p - 1; partition >= 0; partition--) {
407 		int minor = (start | partition);
408 		invalidate_device(MKDEV(MAJOR_NR, minor), 1);
409 		xd_gendisk.part[minor].start_sect = 0;
410 		xd_gendisk.part[minor].nr_sects = 0;
411 	};
412 
413 	grok_partitions(&xd_gendisk, target, 1<<6,
414 			xd_info[target].heads * xd_info[target].cylinders * xd_info[target].sectors);
415 
416 	xd_valid[target] = 1;
417 	wake_up(&xd_wait_open);
418 
419 	return 0;
420 }
421 
422 /* xd_readwrite: handle a read/write request */
xd_readwrite(u8 operation,u8 drive,char * buffer,unsigned int block,unsigned int count)423 static int xd_readwrite (u8 operation,u8 drive,char *buffer,unsigned int block,unsigned int count)
424 {
425 	u8 cmdblk[6],sense[4];
426 	u16 track,cylinder;
427 	u8 head,sector,control,mode = PIO_MODE,temp;
428 	char **real_buffer;
429 
430 #ifdef DEBUG_READWRITE
431 	printk(KERN_DEBUG "xd_readwrite: operation = %s, drive = %d, buffer = 0x%X, block = %d, count = %d\n",operation == READ ? "read" : "write",drive,buffer,block,count);
432 #endif /* DEBUG_READWRITE */
433 
434 	spin_unlock_irq(&io_request_lock);
435 
436 	control = xd_info[drive].control;
437 	while (count) {
438 		temp = count < xd_maxsectors ? count : xd_maxsectors;
439 
440 		track = block / xd_info[drive].sectors;
441 		head = track % xd_info[drive].heads;
442 		cylinder = track / xd_info[drive].heads;
443 		sector = block % xd_info[drive].sectors;
444 
445 #ifdef DEBUG_READWRITE
446 		printk(KERN_DEBUG "xd_readwrite: drive = %d, head = %d, cylinder = %d, sector = %d, count = %d\n",drive,head,cylinder,sector,temp);
447 #endif /* DEBUG_READWRITE */
448 
449 		if (xd_dma_buffer) {
450 			mode = xd_setup_dma(operation == READ ? DMA_MODE_READ : DMA_MODE_WRITE,(u8 *)(xd_dma_buffer),temp * 0x200);
451 			real_buffer = &xd_dma_buffer;
452 			memcpy(xd_dma_buffer, buffer, temp * 0x200);
453 		}
454 		else
455 			real_buffer = &buffer;
456 
457 		xd_build(cmdblk,operation == READ ? CMD_READ : CMD_WRITE,drive,head,cylinder,sector,temp & 0xFF,control);
458 
459 		switch (xd_command(cmdblk,mode,(u8 *)(*real_buffer),(u8 *)(*real_buffer),sense,XD_TIMEOUT))
460 		{
461 			case 1:
462 				printk(KERN_WARNING "xd%c: %s timeout, recalibrating drive\n",'a'+drive,(operation == READ ? "read" : "write"));
463 				xd_recalibrate(drive);
464 				goto fail;
465 			case 2:
466 				if (sense[0] & 0x30) {
467 					printk(KERN_ERR "xd%c: %s - ",'a'+drive,(operation == READ ? "reading" : "writing"));
468 					switch ((sense[0] & 0x30) >> 4) {
469 					case 0: printk("drive error, code = 0x%X",sense[0] & 0x0F);
470 						break;
471 					case 1: printk("controller error, code = 0x%X",sense[0] & 0x0F);
472 						break;
473 					case 2: printk("command error, code = 0x%X",sense[0] & 0x0F);
474 						break;
475 					case 3: printk("miscellaneous error, code = 0x%X",sense[0] & 0x0F);
476 						break;
477 					}
478 				}
479 				if (sense[0] & 0x80)
480 					printk(" - CHS = %d/%d/%d\n",((sense[2] & 0xC0) << 2) | sense[3],sense[1] & 0x1F,sense[2] & 0x3F);
481 				/*	reported drive number = (sense[1] & 0xE0) >> 5 */
482 				else
483 					printk(" - no valid disk address\n");
484 				goto fail;
485 		}
486 		if (xd_dma_buffer)
487 			memcpy(buffer, xd_dma_buffer, (temp * 0x200));
488 
489 		count -= temp, buffer += temp * 0x200, block += temp;
490 	}
491 	spin_lock_irq(&io_request_lock);
492 	return 1;
493 
494 fail:
495 	spin_lock_irq(&io_request_lock);
496 	return 0;
497 
498 }
499 
500 /* xd_recalibrate: recalibrate a given drive and reset controller if necessary */
xd_recalibrate(u8 drive)501 static void xd_recalibrate (u8 drive)
502 {
503 	u8 cmdblk[6];
504 
505 	xd_build(cmdblk,CMD_RECALIBRATE,drive,0,0,0,0,0);
506 	if (xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 8))
507 		printk(KERN_WARNING "xd%c: warning! error recalibrating, controller may be unstable\n", 'a'+drive);
508 }
509 
510 /* xd_interrupt_handler: interrupt service routine */
xd_interrupt_handler(int irq,void * dev_id,struct pt_regs * regs)511 static void xd_interrupt_handler(int irq, void *dev_id, struct pt_regs * regs)
512 {
513 	if (inb(XD_STATUS) & STAT_INTERRUPT) {							/* check if it was our device */
514 #ifdef DEBUG_OTHER
515 		printk(KERN_DEBUG "xd_interrupt_handler: interrupt detected\n");
516 #endif /* DEBUG_OTHER */
517 		outb(0,XD_CONTROL);								/* acknowledge interrupt */
518 		wake_up(&xd_wait_int);								/* and wake up sleeping processes */
519 	}
520 	else
521 		printk(KERN_DEBUG "xd: unexpected interrupt\n");
522 }
523 
524 /* xd_setup_dma: set up the DMA controller for a data transfer */
xd_setup_dma(u8 mode,u8 * buffer,unsigned int count)525 static u8 xd_setup_dma (u8 mode,u8 *buffer,unsigned int count)
526 {
527 	unsigned long f;
528 
529 	if (nodma)
530 		return (PIO_MODE);
531 	if (((unsigned long) buffer & 0xFFFF0000) != (((unsigned long) buffer + count) & 0xFFFF0000)) {
532 #ifdef DEBUG_OTHER
533 		printk(KERN_DEBUG "xd_setup_dma: using PIO, transfer overlaps 64k boundary\n");
534 #endif /* DEBUG_OTHER */
535 		return PIO_MODE;
536 	}
537 
538 	f=claim_dma_lock();
539 	disable_dma(xd_dma);
540 	clear_dma_ff(xd_dma);
541 	set_dma_mode(xd_dma,mode);
542 	set_dma_addr(xd_dma, (unsigned long) buffer);
543 	set_dma_count(xd_dma,count);
544 
545 	release_dma_lock(f);
546 
547 	return DMA_MODE;			/* use DMA and INT */
548 }
549 
550 /* xd_build: put stuff into an array in a format suitable for the controller */
xd_build(u8 * cmdblk,u8 command,u8 drive,u8 head,u16 cylinder,u8 sector,u8 count,u8 control)551 static u8 *xd_build (u8 *cmdblk,u8 command,u8 drive,u8 head,u16 cylinder,u8 sector,u8 count,u8 control)
552 {
553 	cmdblk[0] = command;
554 	cmdblk[1] = ((drive & 0x07) << 5) | (head & 0x1F);
555 	cmdblk[2] = ((cylinder & 0x300) >> 2) | (sector & 0x3F);
556 	cmdblk[3] = cylinder & 0xFF;
557 	cmdblk[4] = count;
558 	cmdblk[5] = control;
559 
560 	return cmdblk;
561 }
562 
563 /* xd_wakeup is called from timer interrupt */
xd_watchdog(unsigned long unused)564 static void xd_watchdog (unsigned long unused)
565 {
566 	xd_error = 1;
567 	wake_up(&xd_wait_int);
568 }
569 
570 /* xd_waitport: waits until port & mask == flags or a timeout occurs. return 1 for a timeout */
xd_waitport(u16 port,u8 flags,u8 mask,unsigned long timeout)571 static inline u8 xd_waitport (u16 port,u8 flags,u8 mask,unsigned long timeout)
572 {
573 	unsigned long expiry = jiffies + timeout;
574 	int success;
575 
576 	xdc_busy = 1;
577 	while ((success = ((inb(port) & mask) != flags)) && time_before(jiffies, expiry)) {
578 		set_current_state(TASK_UNINTERRUPTIBLE);
579 		schedule_timeout(1);
580 	}
581 	xdc_busy = 0;
582 	return (success);
583 }
584 
xd_wait_for_IRQ(void)585 static inline unsigned 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_sync(&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(KERN_DEBUG "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 */
xd_command(u8 * command,u8 mode,u8 * indata,u8 * outdata,u8 * sense,unsigned long timeout)612 static unsigned int xd_command (u8 *command,u8 mode,u8 *indata,u8 *outdata,u8 *sense,unsigned long timeout)
613 {
614 	u8 cmdblk[6];
615 	u8 csb,complete = 0;
616 
617 #ifdef DEBUG_COMMAND
618 	printk(KERN_DEBUG "xd_command: command = 0x%X, mode = 0x%X, indata = 0x%X, outdata = 0x%X, sense = 0x%X\n",command,mode,indata,outdata,sense);
619 #endif /* DEBUG_COMMAND */
620 
621 	outb(0,XD_SELECT);
622 	outb(mode,XD_CONTROL);
623 
624 	if (xd_waitport(XD_STATUS,STAT_SELECT,STAT_SELECT,timeout))
625 		return (1);
626 
627 	while (!complete) {
628 		if (xd_waitport(XD_STATUS,STAT_READY,STAT_READY,timeout))
629 			return (1);
630 
631 		switch (inb(XD_STATUS) & (STAT_COMMAND | STAT_INPUT)) {
632 			case 0:
633 				if (mode == DMA_MODE) {
634 					if (xd_wait_for_IRQ())
635 						return (1);
636 				} else
637 					outb(outdata ? *outdata++ : 0,XD_DATA);
638 				break;
639 			case STAT_INPUT:
640 				if (mode == DMA_MODE) {
641 					if (xd_wait_for_IRQ())
642 						return (1);
643 				} else
644 					if (indata)
645 						*indata++ = inb(XD_DATA);
646 					else
647 						inb(XD_DATA);
648 				break;
649 			case STAT_COMMAND:
650 				outb(command ? *command++ : 0,XD_DATA);
651 				break;
652 			case STAT_COMMAND | STAT_INPUT:
653 				complete = 1;
654 				break;
655 		}
656 	}
657 	csb = inb(XD_DATA);
658 
659 	if (xd_waitport(XD_STATUS,0,STAT_SELECT,timeout))					/* wait until deselected */
660 		return (1);
661 
662 	if (csb & CSB_ERROR) {									/* read sense data if error */
663 		xd_build(cmdblk,CMD_SENSE,(csb & CSB_LUN) >> 5,0,0,0,0,0);
664 		if (xd_command(cmdblk,0,sense,0,0,XD_TIMEOUT))
665 			printk(KERN_DEBUG "xd: warning! sense command failed!\n");
666 	}
667 
668 #ifdef DEBUG_COMMAND
669 	printk(KERN_DEBUG "xd_command: completed with csb = 0x%X\n",csb);
670 #endif /* DEBUG_COMMAND */
671 
672 	return (csb & CSB_ERROR);
673 }
674 
xd_initdrives(void (* init_drive)(u8 drive))675 static u8 __init xd_initdrives (void (*init_drive)(u8 drive))
676 {
677 	u8 cmdblk[6],i,count = 0;
678 
679 	for (i = 0; i < XD_MAXDRIVES; i++) {
680 		xd_build(cmdblk,CMD_TESTREADY,i,0,0,0,0,0);
681 		if (!xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 8)) {
682 			set_current_state(TASK_INTERRUPTIBLE);
683 			schedule_timeout(XD_INIT_DISK_DELAY);
684 
685 			init_drive(count);
686 			count++;
687 
688 			set_current_state(TASK_INTERRUPTIBLE);
689 			schedule_timeout(XD_INIT_DISK_DELAY);
690 		}
691 	}
692 	return (count);
693 }
694 
xd_manual_geo_set(u8 drive)695 static void __init xd_manual_geo_set (u8 drive)
696 {
697 	xd_info[drive].heads 	= xd_geo[3 * drive + 1];
698 	xd_info[drive].cylinders= xd_geo[3 * drive];
699 	xd_info[drive].sectors =  xd_geo[3 * drive + 2];
700 }
701 
xd_dtc_init_controller(unsigned int address)702 static void __init xd_dtc_init_controller (unsigned int address)
703 {
704 	switch (address) {
705 		case 0x00000:
706 		case 0xC8000:
707 			break;			/*initial: 0x320 */
708 		case 0xCA000:
709 			xd_iobase = 0x324;
710 		case 0xD0000:			/*5150CX*/
711 		case 0xD8000:
712 			break;			/*5150CX & 5150XL*/
713 		default:
714 			printk(KERN_ERR "xd_dtc_init_controller: unsupported BIOS address %06x\n",address);
715 			break;
716 	}
717 	xd_maxsectors = 0x01;		/* my card seems to have trouble doing multi-block transfers? */
718 
719 	outb(0,XD_RESET);		/* reset the controller */
720 }
721 
722 
xd_dtc5150cx_init_drive(u8 drive)723 static void __init xd_dtc5150cx_init_drive (u8 drive)
724 {
725 	/* values from controller's BIOS - BIOS chip may be removed */
726 	static u16 geometry_table[][4] = {
727 		{0x200,8,0x200,0x100},
728 		{0x267,2,0x267,0x267},
729 		{0x264,4,0x264,0x80},
730 		{0x132,4,0x132,0x0},
731 		{0x132,2,0x80, 0x132},
732 		{0x177,8,0x177,0x0},
733 		{0x132,8,0x84, 0x0},
734 		{},  /* not used */
735 		{0x132,6,0x80, 0x100},
736 		{0x200,6,0x100,0x100},
737 		{0x264,2,0x264,0x80},
738 		{0x280,4,0x280,0x100},
739 		{0x2B9,3,0x2B9,0x2B9},
740 		{0x2B9,5,0x2B9,0x2B9},
741 		{0x280,6,0x280,0x100},
742 		{0x132,4,0x132,0x0}};
743 	u8 n;
744 
745 	n = inb(XD_JUMPER);
746 	n = (drive ? n : (n >> 2)) & 0x33;
747 	n = (n | (n >> 2)) & 0x0F;
748 	if (xd_geo[3*drive])
749 		xd_manual_geo_set(drive);
750 	else
751 		if (n != 7) {
752 			xd_info[drive].heads = (u8)(geometry_table[n][1]);			/* heads */
753 			xd_info[drive].cylinders = geometry_table[n][0];	/* cylinders */
754 			xd_info[drive].sectors = 17;				/* sectors */
755 #if 0
756 			xd_info[drive].rwrite = geometry_table[n][2];	/* reduced write */
757 			xd_info[drive].precomp = geometry_table[n][3]		/* write precomp */
758 			xd_info[drive].ecc = 0x0B;				/* ecc length */
759 #endif /* 0 */
760 		}
761 		else {
762 			printk(KERN_WARNING "xd%c: undetermined drive geometry\n",'a'+drive);
763 			return;
764 		}
765 	xd_info[drive].control = 5;				/* control byte */
766 	xd_setparam(CMD_DTCSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,geometry_table[n][2],geometry_table[n][3],0x0B);
767 	xd_recalibrate(drive);
768 }
769 
xd_dtc_init_drive(u8 drive)770 static void __init xd_dtc_init_drive (u8 drive)
771 {
772 	u8 cmdblk[6],buf[64];
773 
774 	xd_build(cmdblk,CMD_DTCGETGEOM,drive,0,0,0,0,0);
775 	if (!xd_command(cmdblk,PIO_MODE,buf,0,0,XD_TIMEOUT * 2)) {
776 		xd_info[drive].heads = buf[0x0A];			/* heads */
777 		xd_info[drive].cylinders = ((u16 *) (buf))[0x04];	/* cylinders */
778 		xd_info[drive].sectors = 17;				/* sectors */
779 		if (xd_geo[3*drive])
780 			xd_manual_geo_set(drive);
781 #if 0
782 		xd_info[drive].rwrite = ((u16 *) (buf + 1))[0x05];	/* reduced write */
783 		xd_info[drive].precomp = ((u16 *) (buf + 1))[0x06];	/* write precomp */
784 		xd_info[drive].ecc = buf[0x0F];				/* ecc length */
785 #endif /* 0 */
786 		xd_info[drive].control = 0;				/* control byte */
787 
788 		xd_setparam(CMD_DTCSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,((u16 *) (buf + 1))[0x05],((u16 *) (buf + 1))[0x06],buf[0x0F]);
789 		xd_build(cmdblk,CMD_DTCSETSTEP,drive,0,0,0,0,7);
790 		if (xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 2))
791 			printk(KERN_WARNING "xd_dtc_init_drive: error setting step rate for xd%c\n", 'a'+drive);
792 	}
793 	else
794 		printk(KERN_WARNING "xd_dtc_init_drive: error reading geometry for xd%c\n", 'a'+drive);
795 }
796 
xd_wd_init_controller(unsigned int address)797 static void __init xd_wd_init_controller (unsigned int address)
798 {
799 	switch (address) {
800 		case 0x00000:
801 		case 0xC8000:	break;			/*initial: 0x320 */
802 		case 0xCA000:	xd_iobase = 0x324; break;
803 		case 0xCC000:   xd_iobase = 0x328; break;
804 		case 0xCE000:   xd_iobase = 0x32C; break;
805 		case 0xD0000:	xd_iobase = 0x328; break; /* ? */
806 		case 0xD8000:	xd_iobase = 0x32C; break; /* ? */
807 		default:        printk(KERN_ERR "xd_wd_init_controller: unsupported BIOS address %06x\n",address);
808 				break;
809 	}
810 	xd_maxsectors = 0x01;		/* this one doesn't wrap properly either... */
811 
812 	outb(0,XD_RESET);		/* reset the controller */
813 
814 	set_current_state(TASK_UNINTERRUPTIBLE);
815 	schedule_timeout(XD_INIT_DISK_DELAY);
816 }
817 
xd_wd_init_drive(u8 drive)818 static void __init xd_wd_init_drive (u8 drive)
819 {
820 	/* values from controller's BIOS - BIOS may be disabled */
821 	static u16 geometry_table[][4] = {
822 		{0x264,4,0x1C2,0x1C2},   /* common part */
823 		{0x132,4,0x099,0x0},
824 		{0x267,2,0x1C2,0x1C2},
825 		{0x267,4,0x1C2,0x1C2},
826 
827 		{0x334,6,0x335,0x335},   /* 1004 series RLL */
828 		{0x30E,4,0x30F,0x3DC},
829 		{0x30E,2,0x30F,0x30F},
830 		{0x267,4,0x268,0x268},
831 
832 		{0x3D5,5,0x3D6,0x3D6},   /* 1002 series RLL */
833 		{0x3DB,7,0x3DC,0x3DC},
834 		{0x264,4,0x265,0x265},
835 		{0x267,4,0x268,0x268}};
836 
837 	u8 cmdblk[6],buf[0x200];
838 	u8 n = 0,rll,jumper_state,use_jumper_geo;
839 	u8 wd_1002 = (xd_sigs[xd_type].string[7] == '6');
840 
841 	jumper_state = ~(inb(0x322));
842 	if (jumper_state & 0x40)
843 		xd_irq = 9;
844 	rll = (jumper_state & 0x30) ? (0x04 << wd_1002) : 0;
845 	xd_build(cmdblk,CMD_READ,drive,0,0,0,1,0);
846 	if (!xd_command(cmdblk,PIO_MODE,buf,0,0,XD_TIMEOUT * 2)) {
847 		xd_info[drive].heads = buf[0x1AF];				/* heads */
848 		xd_info[drive].cylinders = ((u16 *) (buf + 1))[0xD6];	/* cylinders */
849 		xd_info[drive].sectors = 17;					/* sectors */
850 		if (xd_geo[3*drive])
851 			xd_manual_geo_set(drive);
852 #if 0
853 		xd_info[drive].rwrite = ((u16 *) (buf))[0xD8];		/* reduced write */
854 		xd_info[drive].wprecomp = ((u16 *) (buf))[0xDA];		/* write precomp */
855 		xd_info[drive].ecc = buf[0x1B4];				/* ecc length */
856 #endif /* 0 */
857 		xd_info[drive].control = buf[0x1B5];				/* control byte */
858 		use_jumper_geo = !(xd_info[drive].heads) || !(xd_info[drive].cylinders);
859 		if (xd_geo[3*drive]) {
860 			xd_manual_geo_set(drive);
861 			xd_info[drive].control = rll ? 7 : 5;
862 		}
863 		else if (use_jumper_geo) {
864 			n = (((jumper_state & 0x0F) >> (drive << 1)) & 0x03) | rll;
865 			xd_info[drive].cylinders = geometry_table[n][0];
866 			xd_info[drive].heads = (u8)(geometry_table[n][1]);
867 			xd_info[drive].control = rll ? 7 : 5;
868 #if 0
869 			xd_info[drive].rwrite = geometry_table[n][2];
870 			xd_info[drive].wprecomp = geometry_table[n][3];
871 			xd_info[drive].ecc = 0x0B;
872 #endif /* 0 */
873 		}
874 		if (!wd_1002) {
875 			if (use_jumper_geo)
876 				xd_setparam(CMD_WDSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,
877 					geometry_table[n][2],geometry_table[n][3],0x0B);
878 			else
879 				xd_setparam(CMD_WDSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,
880 					((u16 *) (buf))[0xD8],((u16 *) (buf))[0xDA],buf[0x1B4]);
881 		}
882 	/* 1002 based RLL controller requests converted addressing, but reports physical
883 	   (physical 26 sec., logical 17 sec.)
884 	   1004 based ???? */
885 		if (rll & wd_1002) {
886 			if ((xd_info[drive].cylinders *= 26,
887 			     xd_info[drive].cylinders /= 17) > 1023)
888 				xd_info[drive].cylinders = 1023;  /* 1024 ? */
889 #if 0
890 			xd_info[drive].rwrite *= 26;
891 			xd_info[drive].rwrite /= 17;
892 			xd_info[drive].wprecomp *= 26
893 			xd_info[drive].wprecomp /= 17;
894 #endif /* 0 */
895 		}
896 	}
897 	else
898 		printk(KERN_WARNING "xd_wd_init_drive: error reading geometry for xd%c\n",'a'+drive);
899 
900 }
901 
xd_seagate_init_controller(unsigned int address)902 static void __init xd_seagate_init_controller (unsigned int address)
903 {
904 	switch (address) {
905 		case 0x00000:
906 		case 0xC8000:	break;			/*initial: 0x320 */
907 		case 0xD0000:	xd_iobase = 0x324; break;
908 		case 0xD8000:	xd_iobase = 0x328; break;
909 		case 0xE0000:	xd_iobase = 0x32C; break;
910 		default:	printk(KERN_ERR "xd_seagate_init_controller: unsupported BIOS address %06x\n",address);
911 				break;
912 	}
913 	xd_maxsectors = 0x40;
914 
915 	outb(0,XD_RESET);		/* reset the controller */
916 }
917 
xd_seagate_init_drive(u8 drive)918 static void __init xd_seagate_init_drive (u8 drive)
919 {
920 	u8 cmdblk[6],buf[0x200];
921 
922 	xd_build(cmdblk,CMD_ST11GETGEOM,drive,0,0,0,1,0);
923 	if (!xd_command(cmdblk,PIO_MODE,buf,0,0,XD_TIMEOUT * 2)) {
924 		xd_info[drive].heads = buf[0x04];				/* heads */
925 		xd_info[drive].cylinders = (buf[0x02] << 8) | buf[0x03];	/* cylinders */
926 		xd_info[drive].sectors = buf[0x05];				/* sectors */
927 		xd_info[drive].control = 0;					/* control byte */
928 	}
929 	else
930 		printk(KERN_WARNING "xd_seagate_init_drive: error reading geometry from xd%c\n", 'a'+drive);
931 }
932 
933 /* Omti support courtesy Dirk Melchers */
xd_omti_init_controller(unsigned int address)934 static void __init xd_omti_init_controller (unsigned int address)
935 {
936 	switch (address) {
937 		case 0x00000:
938 		case 0xC8000:	break;			/*initial: 0x320 */
939 		case 0xD0000:	xd_iobase = 0x324; break;
940 		case 0xD8000:	xd_iobase = 0x328; break;
941 		case 0xE0000:	xd_iobase = 0x32C; break;
942 		default:	printk(KERN_ERR "xd_omti_init_controller: unsupported BIOS address %06x\n",address);
943 				break;
944 	}
945 
946 	xd_maxsectors = 0x40;
947 
948 	outb(0,XD_RESET);		/* reset the controller */
949 }
950 
xd_omti_init_drive(u8 drive)951 static void __init xd_omti_init_drive (u8 drive)
952 {
953 	/* gets infos from drive */
954 	xd_override_init_drive(drive);
955 
956 	/* set other parameters, Hardcoded, not that nice :-) */
957 	xd_info[drive].control = 2;
958 }
959 
960 /* Xebec support (AK) */
xd_xebec_init_controller(unsigned int address)961 static void __init xd_xebec_init_controller (unsigned int address)
962 {
963 /* iobase may be set manually in range 0x300 - 0x33C
964       irq may be set manually to 2(9),3,4,5,6,7
965       dma may be set manually to 1,2,3
966 	(How to detect them ???)
967 BIOS address may be set manually in range 0x0 - 0xF8000
968 If you need non-standard settings use the xd=... command */
969 
970 	switch (address) {
971 		case 0x00000:
972 		case 0xC8000:	/* initially: xd_iobase==0x320 */
973 		case 0xD0000:
974 		case 0xD2000:
975 		case 0xD4000:
976 		case 0xD6000:
977 		case 0xD8000:
978 		case 0xDA000:
979 		case 0xDC000:
980 		case 0xDE000:
981 		case 0xE0000:	break;
982 		default:	printk(KERN_ERR "xd_xebec_init_controller: unsupported BIOS address %06x\n",address);
983 				break;
984 		}
985 
986 	xd_maxsectors = 0x01;
987 	outb(0,XD_RESET);		/* reset the controller */
988 
989 	set_current_state(TASK_UNINTERRUPTIBLE);
990 	schedule_timeout(XD_INIT_DISK_DELAY);
991 }
992 
xd_xebec_init_drive(u8 drive)993 static void __init xd_xebec_init_drive (u8 drive)
994 {
995 	/* values from controller's BIOS - BIOS chip may be removed */
996 	static u16 geometry_table[][5] = {
997 		{0x132,4,0x080,0x080,0x7},
998 		{0x132,4,0x080,0x080,0x17},
999 		{0x264,2,0x100,0x100,0x7},
1000 		{0x264,2,0x100,0x100,0x17},
1001 		{0x132,8,0x080,0x080,0x7},
1002 		{0x132,8,0x080,0x080,0x17},
1003 		{0x264,4,0x100,0x100,0x6},
1004 		{0x264,4,0x100,0x100,0x17},
1005 		{0x2BC,5,0x2BC,0x12C,0x6},
1006 		{0x3A5,4,0x3A5,0x3A5,0x7},
1007 		{0x26C,6,0x26C,0x26C,0x7},
1008 		{0x200,8,0x200,0x100,0x17},
1009 		{0x400,5,0x400,0x400,0x7},
1010 		{0x400,6,0x400,0x400,0x7},
1011 		{0x264,8,0x264,0x200,0x17},
1012 		{0x33E,7,0x33E,0x200,0x7}};
1013 	u8 n;
1014 
1015 	n = inb(XD_JUMPER) & 0x0F; /* BIOS's drive number: same geometry
1016 					is assumed for BOTH drives */
1017 	if (xd_geo[3*drive])
1018 		xd_manual_geo_set(drive);
1019 	else {
1020 		xd_info[drive].heads = (u8)(geometry_table[n][1]);			/* heads */
1021 		xd_info[drive].cylinders = geometry_table[n][0];	/* cylinders */
1022 		xd_info[drive].sectors = 17;				/* sectors */
1023 #if 0
1024 		xd_info[drive].rwrite = geometry_table[n][2];	/* reduced write */
1025 		xd_info[drive].precomp = geometry_table[n][3]		/* write precomp */
1026 		xd_info[drive].ecc = 0x0B;				/* ecc length */
1027 #endif /* 0 */
1028 	}
1029 	xd_info[drive].control = geometry_table[n][4];			/* control byte */
1030 	xd_setparam(CMD_XBSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,geometry_table[n][2],geometry_table[n][3],0x0B);
1031 	xd_recalibrate(drive);
1032 }
1033 
1034 /* xd_override_init_drive: this finds disk geometry in a "binary search" style, narrowing in on the "correct" number of heads
1035    etc. by trying values until it gets the highest successful value. Idea courtesy Salvador Abreu (spa@fct.unl.pt). */
xd_override_init_drive(u8 drive)1036 static void __init xd_override_init_drive (u8 drive)
1037 {
1038 	u16 min[] = { 0,0,0 },max[] = { 16,1024,64 },test[] = { 0,0,0 };
1039 	u8 cmdblk[6],i;
1040 
1041 	if (xd_geo[3*drive])
1042 		xd_manual_geo_set(drive);
1043 	else {
1044 		for (i = 0; i < 3; i++) {
1045 			while (min[i] != max[i] - 1) {
1046 				test[i] = (min[i] + max[i]) / 2;
1047 				xd_build(cmdblk,CMD_SEEK,drive,(u8) test[0],(u16) test[1],(u8) test[2],0,0);
1048 				if (!xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 2))
1049 					min[i] = test[i];
1050 				else
1051 					max[i] = test[i];
1052 			}
1053 			test[i] = min[i];
1054 		}
1055 		xd_info[drive].heads = (u8) min[0] + 1;
1056 		xd_info[drive].cylinders = (u16) min[1] + 1;
1057 		xd_info[drive].sectors = (u8) min[2] + 1;
1058 	}
1059 	xd_info[drive].control = 0;
1060 }
1061 
1062 /* xd_setup: initialise controller from command line parameters */
do_xd_setup(int * integers)1063 void __init do_xd_setup (int *integers)
1064 {
1065 	switch (integers[0]) {
1066 		case 4: if (integers[4] < 0)
1067 				nodma = 1;
1068 			else if (integers[4] < 8)
1069 				xd_dma = integers[4];
1070 		case 3: if ((integers[3] > 0) && (integers[3] <= 0x3FC))
1071 				xd_iobase = integers[3];
1072 		case 2: if ((integers[2] > 0) && (integers[2] < 16))
1073 				xd_irq = integers[2];
1074 		case 1: xd_override = 1;
1075 			if ((integers[1] >= 0) && (integers[1] < (sizeof(xd_sigs) / sizeof(xd_sigs[0]))))
1076 				xd_type = integers[1];
1077 		case 0: break;
1078 		default:printk(KERN_ERR "xd: too many parameters for xd\n");
1079 	}
1080 	xd_maxsectors = 0x01;
1081 }
1082 
1083 /* xd_setparam: set the drive characteristics */
xd_setparam(u8 command,u8 drive,u8 heads,u16 cylinders,u16 rwrite,u16 wprecomp,u8 ecc)1084 static void __init xd_setparam (u8 command,u8 drive,u8 heads,u16 cylinders,u16 rwrite,u16 wprecomp,u8 ecc)
1085 {
1086 	u8 cmdblk[14];
1087 
1088 	xd_build(cmdblk,command,drive,0,0,0,0,0);
1089 	cmdblk[6] = (u8) (cylinders >> 8) & 0x03;
1090 	cmdblk[7] = (u8) (cylinders & 0xFF);
1091 	cmdblk[8] = heads & 0x1F;
1092 	cmdblk[9] = (u8) (rwrite >> 8) & 0x03;
1093 	cmdblk[10] = (u8) (rwrite & 0xFF);
1094 	cmdblk[11] = (u8) (wprecomp >> 8) & 0x03;
1095 	cmdblk[12] = (u8) (wprecomp & 0xFF);
1096 	cmdblk[13] = ecc;
1097 
1098 	/* Some controllers require geometry info as data, not command */
1099 
1100 	if (xd_command(cmdblk,PIO_MODE,0,&cmdblk[6],0,XD_TIMEOUT * 2))
1101 		printk(KERN_WARNING "xd: error setting characteristics for xd%c\n", 'a'+drive);
1102 }
1103 
1104 
1105 #ifdef MODULE
1106 static int xd[5] = { -1,-1,-1,-1, };
1107 
1108 MODULE_PARM(xd, "1-4i");
1109 MODULE_PARM(xd_geo, "3-6i");
1110 MODULE_PARM(nodma, "i");
1111 
1112 MODULE_LICENSE("GPL");
1113 
xd_done(void)1114 static void xd_done (void)
1115 {
1116 	blksize_size[MAJOR_NR] = NULL;
1117 	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
1118 	blk_size[MAJOR_NR] = NULL;
1119 	hardsect_size[MAJOR_NR] = NULL;
1120 	read_ahead[MAJOR_NR] = 0;
1121 	del_gendisk(&xd_gendisk);
1122 	release_region(xd_iobase,4);
1123 }
1124 
init_module(void)1125 int init_module(void)
1126 {
1127 	int i,count = 0;
1128 	int error;
1129 
1130 	for (i = 4; i > 0; i--)
1131 		if(((xd[i] = xd[i-1]) >= 0) && !count)
1132 			count = i;
1133 	if((xd[0] = count))
1134 		do_xd_setup(xd);
1135 
1136 	error = xd_init();
1137 	if (error) return error;
1138 
1139 	printk(KERN_INFO "XD: Loaded as a module.\n");
1140 	if (!xd_drives) {
1141 		/* no drives detected - unload module */
1142 		devfs_unregister_blkdev(MAJOR_NR, "xd");
1143 		xd_done();
1144 		return (-1);
1145 	}
1146 
1147 	return 0;
1148 }
1149 
cleanup_module(void)1150 void cleanup_module(void)
1151 {
1152 	devfs_unregister_blkdev(MAJOR_NR, "xd");
1153 	xd_done();
1154 	devfs_unregister(devfs_handle);
1155 	if (xd_drives) {
1156 		free_irq(xd_irq, NULL);
1157 		free_dma(xd_dma);
1158 		if (xd_dma_buffer)
1159 			xd_dma_mem_free((unsigned long)xd_dma_buffer, xd_maxsectors * 0x200);
1160 	}
1161 }
1162 #else
1163 
xd_setup(char * str)1164 static int __init xd_setup (char *str)
1165 {
1166 	int ints[5];
1167 	get_options (str, ARRAY_SIZE (ints), ints);
1168 	do_xd_setup (ints);
1169 	return 1;
1170 }
1171 
1172 /* xd_manual_geo_init: initialise drive geometry from command line parameters
1173    (used only for WD drives) */
xd_manual_geo_init(char * str)1174 static int __init xd_manual_geo_init (char *str)
1175 {
1176 	int i, integers[1 + 3*XD_MAXDRIVES];
1177 
1178 	get_options (str, ARRAY_SIZE (integers), integers);
1179 	if (integers[0]%3 != 0) {
1180 		printk(KERN_ERR "xd: incorrect number of parameters for xd_geo\n");
1181 		return 1;
1182 	}
1183 	for (i = 0; (i < integers[0]) && (i < 3*XD_MAXDRIVES); i++)
1184 		xd_geo[i] = integers[i+1];
1185 	return 1;
1186 }
1187 
1188 __setup ("xd=", xd_setup);
1189 __setup ("xd_geo=", xd_manual_geo_init);
1190 
1191 #endif /* MODULE */
1192 
1193