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