/*
 * This file contains the driver for an XT hard disk controller
 * (at least the DTC 5150X) for Linux.
 *
 * Author: Pat Mackinlay, pat@it.com.au
 * Date: 29/09/92
 * 
 * Revised: 01/01/93, ...
 *
 * Ref: DTC 5150X Controller Specification (thanks to Kevin Fowler,
 *   kevinf@agora.rain.com)
 * Also thanks to: Salvador Abreu, Dave Thaler, Risto Kankkunen and
 *   Wim Van Dorst.
 *
 * Revised: 04/04/94 by Risto Kankkunen
 *   Moved the detection code from xd_init() to xd_geninit() as it needed
 *   interrupts enabled and Linus didn't want to enable them in that first
 *   phase. xd_geninit() is the place to do these kinds of things anyway,
 *   he says.
 *
 * Modularized: 04/10/96 by Todd Fries, tfries@umr.edu
 *
 * Revised: 13/12/97 by Andrzej Krzysztofowicz, ankry@mif.pg.gda.pl
 *   Fixed some problems with disk initialization and module initiation.
 *   Added support for manual geometry setting (except Seagate controllers)
 *   in form:
 *      xd_geo=<cyl_xda>,<head_xda>,<sec_xda>[,<cyl_xdb>,<head_xdb>,<sec_xdb>]
 *   Recovered DMA access. Abridged messages. Added support for DTC5051CX,
 *   WD1002-27X & XEBEC controllers. Driver uses now some jumper settings.
 *   Extended ioctl() support.
 *
 * Bugfix: 15/02/01, Paul G. - inform queue layer of tiny xd_maxsect.
 *
 */

#include <linux/module.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/timer.h>
#include <linux/genhd.h>
#include <linux/hdreg.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/wait.h>
#include <linux/blkdev.h>
#include <linux/mutex.h>
#include <linux/blkpg.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/gfp.h>

#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/dma.h>

#include "xd.h"

static DEFINE_MUTEX(xd_mutex);
static void __init do_xd_setup (int *integers);
#ifdef MODULE
static int xd[5] = { -1,-1,-1,-1, };
#endif

#define XD_DONT_USE_DMA		0  /* Initial value. may be overriden using
				      "nodma" module option */
#define XD_INIT_DISK_DELAY	(30)  /* 30 ms delay during disk initialization */

/* Above may need to be increased if a problem with the 2nd drive detection
   (ST11M controller) or resetting a controller (WD) appears */

static XD_INFO xd_info[XD_MAXDRIVES];

/* If you try this driver and find that your card is not detected by the driver at bootup, you need to add your BIOS
   signature and details to the following list of signatures. A BIOS signature is a string embedded into the first
   few bytes of your controller's on-board ROM BIOS. To find out what yours is, use something like MS-DOS's DEBUG
   command. Run DEBUG, and then you can examine your BIOS signature with:

	d xxxx:0000

   where xxxx is the segment of your controller (like C800 or D000 or something). On the ASCII dump at the right, you should
   be able to see a string mentioning the manufacturer's copyright etc. Add this string into the table below. The parameters
   in the table are, in order:

	offset			; this is the offset (in bytes) from the start of your ROM where the signature starts
	signature		; this is the actual text of the signature
	xd_?_init_controller	; this is the controller init routine used by your controller
	xd_?_init_drive		; this is the drive init routine used by your controller

   The controllers directly supported at the moment are: DTC 5150x, WD 1004A27X, ST11M/R and override. If your controller is
   made by the same manufacturer as one of these, try using the same init routines as they do. If that doesn't work, your
   best bet is to use the "override" routines. These routines use a "portable" method of getting the disk's geometry, and
   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>.

   NOTE: You can now specify your XT controller's parameters from the command line in the form xd=TYPE,IRQ,IO,DMA. The driver
   should be able to detect your drive's geometry from this info. (eg: xd=0,5,0x320,3 is the "standard"). */

#include <asm/page.h>
#define xd_dma_mem_alloc(size) __get_dma_pages(GFP_KERNEL,get_order(size))
#define xd_dma_mem_free(addr, size) free_pages(addr, get_order(size))
static char *xd_dma_buffer;

static XD_SIGNATURE xd_sigs[] __initdata = {
	{ 0x0000,"Override geometry handler",NULL,xd_override_init_drive,"n unknown" }, /* Pat Mackinlay, pat@it.com.au */
	{ 0x0008,"[BXD06 (C) DTC 17-MAY-1985]",xd_dtc_init_controller,xd_dtc5150cx_init_drive," DTC 5150CX" }, /* Andrzej Krzysztofowicz, ankry@mif.pg.gda.pl */
	{ 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 */
	{ 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 */
	{ 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 */
	{ 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 */
	{ 0x0015,"SEAGATE ST11 BIOS REVISION",xd_seagate_init_controller,xd_seagate_init_drive," Seagate ST11M/R" }, /* Salvador Abreu, spa@fct.unl.pt */
	{ 0x0010,"ST11R BIOS",xd_seagate_init_controller,xd_seagate_init_drive," Seagate ST11M/R" }, /* Risto Kankkunen, risto.kankkunen@cs.helsinki.fi */
	{ 0x0010,"ST11 BIOS v1.7",xd_seagate_init_controller,xd_seagate_init_drive," Seagate ST11R" }, /* Alan Hourihane, alanh@fairlite.demon.co.uk */
	{ 0x1000,"(c)Copyright 1987 SMS",xd_omti_init_controller,xd_omti_init_drive,"n OMTI 5520" }, /* Dirk Melchers, dirk@merlin.nbg.sub.org */
	{ 0x0006,"COPYRIGHT XEBEC (C) 1984",xd_xebec_init_controller,xd_xebec_init_drive," XEBEC" }, /* Andrzej Krzysztofowicz, ankry@mif.pg.gda.pl */
	{ 0x0008,"(C) Copyright 1984 Western Digital Corp", xd_wd_init_controller, xd_wd_init_drive," Western Dig. 1002s-wx2" },
	{ 0x0008,"(C) Copyright 1986 Western Digital Corporation", xd_wd_init_controller, xd_wd_init_drive," 1986 Western Digital" }, /* jfree@sovereign.org */
};

static unsigned int xd_bases[] __initdata =
{
	0xC8000, 0xCA000, 0xCC000,
	0xCE000, 0xD0000, 0xD2000,
	0xD4000, 0xD6000, 0xD8000,
	0xDA000, 0xDC000, 0xDE000,
	0xE0000
};

static DEFINE_SPINLOCK(xd_lock);

static struct gendisk *xd_gendisk[2];

static int xd_getgeo(struct block_device *bdev, struct hd_geometry *geo);

static const struct block_device_operations xd_fops = {
	.owner	= THIS_MODULE,
	.ioctl	= xd_ioctl,
	.getgeo = xd_getgeo,
};
static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int);
static u_char xd_drives, xd_irq = 5, xd_dma = 3, xd_maxsectors;
static u_char xd_override __initdata = 0, xd_type __initdata = 0;
static u_short xd_iobase = 0x320;
static int xd_geo[XD_MAXDRIVES*3] __initdata = { 0, };

static volatile int xdc_busy;
static struct timer_list xd_watchdog_int;

static volatile u_char xd_error;
static int nodma = XD_DONT_USE_DMA;

static struct request_queue *xd_queue;

/* xd_init: register the block device number and set up pointer tables */
static int __init xd_init(void)
{
	u_char i,controller;
	unsigned int address;
	int err;

#ifdef MODULE
	{
		u_char count = 0;
		for (i = 4; i > 0; i--)
			if (((xd[i] = xd[i-1]) >= 0) && !count)
				count = i;
		if ((xd[0] = count))
			do_xd_setup(xd);
	}
#endif

	init_timer (&xd_watchdog_int); xd_watchdog_int.function = xd_watchdog;

	err = -EBUSY;
	if (register_blkdev(XT_DISK_MAJOR, "xd"))
		goto out1;

	err = -ENOMEM;
	xd_queue = blk_init_queue(do_xd_request, &xd_lock);
	if (!xd_queue)
		goto out1a;

	if (xd_detect(&controller,&address)) {

		printk("Detected a%s controller (type %d) at address %06x\n",
			xd_sigs[controller].name,controller,address);
		if (!request_region(xd_iobase,4,"xd")) {
			printk("xd: Ports at 0x%x are not available\n",
				xd_iobase);
			goto out2;
		}
		if (controller)
			xd_sigs[controller].init_controller(address);
		xd_drives = xd_initdrives(xd_sigs[controller].init_drive);
		
		printk("Detected %d hard drive%s (using IRQ%d & DMA%d)\n",
			xd_drives,xd_drives == 1 ? "" : "s",xd_irq,xd_dma);
	}

	/*
	 * With the drive detected, xd_maxsectors should now be known.
	 * If xd_maxsectors is 0, nothing was detected and we fall through
	 * to return -ENODEV
	 */
	if (!xd_dma_buffer && xd_maxsectors) {
		xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
		if (!xd_dma_buffer) {
			printk(KERN_ERR "xd: Out of memory.\n");
			goto out3;
		}
	}

	err = -ENODEV;
	if (!xd_drives)
		goto out3;

	for (i = 0; i < xd_drives; i++) {
		XD_INFO *p = &xd_info[i];
		struct gendisk *disk = alloc_disk(64);
		if (!disk)
			goto Enomem;
		p->unit = i;
		disk->major = XT_DISK_MAJOR;
		disk->first_minor = i<<6;
		sprintf(disk->disk_name, "xd%c", i+'a');
		disk->fops = &xd_fops;
		disk->private_data = p;
		disk->queue = xd_queue;
		set_capacity(disk, p->heads * p->cylinders * p->sectors);
		printk(" %s: CHS=%d/%d/%d\n", disk->disk_name,
			p->cylinders, p->heads, p->sectors);
		xd_gendisk[i] = disk;
	}

	err = -EBUSY;
	if (request_irq(xd_irq,xd_interrupt_handler, 0, "XT hard disk", NULL)) {
		printk("xd: unable to get IRQ%d\n",xd_irq);
		goto out4;
	}

	if (request_dma(xd_dma,"xd")) {
		printk("xd: unable to get DMA%d\n",xd_dma);
		goto out5;
	}

	/* xd_maxsectors depends on controller - so set after detection */
	blk_queue_max_hw_sectors(xd_queue, xd_maxsectors);

	for (i = 0; i < xd_drives; i++)
		add_disk(xd_gendisk[i]);

	return 0;

out5:
	free_irq(xd_irq, NULL);
out4:
	for (i = 0; i < xd_drives; i++)
		put_disk(xd_gendisk[i]);
out3:
	if (xd_maxsectors)
		release_region(xd_iobase,4);

	if (xd_dma_buffer)
		xd_dma_mem_free((unsigned long)xd_dma_buffer,
				xd_maxsectors * 0x200);
out2:
	blk_cleanup_queue(xd_queue);
out1a:
	unregister_blkdev(XT_DISK_MAJOR, "xd");
out1:
	return err;
Enomem:
	err = -ENOMEM;
	while (i--)
		put_disk(xd_gendisk[i]);
	goto out3;
}

/* xd_detect: scan the possible BIOS ROM locations for the signature strings */
static u_char __init xd_detect (u_char *controller, unsigned int *address)
{
	int i, j;

	if (xd_override)
	{
		*controller = xd_type;
		*address = 0;
		return(1);
	}

	for (i = 0; i < ARRAY_SIZE(xd_bases); i++) {
		void __iomem *p = ioremap(xd_bases[i], 0x2000);
		if (!p)
			continue;
		for (j = 1; j < ARRAY_SIZE(xd_sigs); j++) {
			const char *s = xd_sigs[j].string;
			if (check_signature(p + xd_sigs[j].offset, s, strlen(s))) {
				*controller = j;
				xd_type = j;
				*address = xd_bases[i];
				iounmap(p);
				return 1;
			}
		}
		iounmap(p);
	}
	return 0;
}

/* do_xd_request: handle an incoming request */
static void do_xd_request (struct request_queue * q)
{
	struct request *req;

	if (xdc_busy)
		return;

	req = blk_fetch_request(q);
	while (req) {
		unsigned block = blk_rq_pos(req);
		unsigned count = blk_rq_cur_sectors(req);
		XD_INFO *disk = req->rq_disk->private_data;
		int res = -EIO;
		int retry;

		if (req->cmd_type != REQ_TYPE_FS)
			goto done;
		if (block + count > get_capacity(req->rq_disk))
			goto done;
		for (retry = 0; (retry < XD_RETRIES) && !res; retry++)
			res = xd_readwrite(rq_data_dir(req), disk, req->buffer,
					   block, count);
	done:
		/* wrap up, 0 = success, -errno = fail */
		if (!__blk_end_request_cur(req, res))
			req = blk_fetch_request(q);
	}
}

static int xd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
{
	XD_INFO *p = bdev->bd_disk->private_data;

	geo->heads = p->heads;
	geo->sectors = p->sectors;
	geo->cylinders = p->cylinders;
	return 0;
}

/* xd_ioctl: handle device ioctl's */
static int xd_locked_ioctl(struct block_device *bdev, fmode_t mode, u_int cmd, u_long arg)
{
	switch (cmd) {
		case HDIO_SET_DMA:
			if (!capable(CAP_SYS_ADMIN)) return -EACCES;
			if (xdc_busy) return -EBUSY;
			nodma = !arg;
			if (nodma && xd_dma_buffer) {
				xd_dma_mem_free((unsigned long)xd_dma_buffer,
						xd_maxsectors * 0x200);
				xd_dma_buffer = NULL;
			} else if (!nodma && !xd_dma_buffer) {
				xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
				if (!xd_dma_buffer) {
					nodma = XD_DONT_USE_DMA;
					return -ENOMEM;
				}
			}
			return 0;
		case HDIO_GET_DMA:
			return put_user(!nodma, (long __user *) arg);
		case HDIO_GET_MULTCOUNT:
			return put_user(xd_maxsectors, (long __user *) arg);
		default:
			return -EINVAL;
	}
}

static int xd_ioctl(struct block_device *bdev, fmode_t mode,
			     unsigned int cmd, unsigned long param)
{
	int ret;

	mutex_lock(&xd_mutex);
	ret = xd_locked_ioctl(bdev, mode, cmd, param);
	mutex_unlock(&xd_mutex);

	return ret;
}

/* xd_readwrite: handle a read/write request */
static int xd_readwrite (u_char operation,XD_INFO *p,char *buffer,u_int block,u_int count)
{
	int drive = p->unit;
	u_char cmdblk[6],sense[4];
	u_short track,cylinder;
	u_char head,sector,control,mode = PIO_MODE,temp;
	char **real_buffer;
	register int i;
	
#ifdef DEBUG_READWRITE
	printk("xd_readwrite: operation = %s, drive = %d, buffer = 0x%X, block = %d, count = %d\n",operation == READ ? "read" : "write",drive,buffer,block,count);
#endif /* DEBUG_READWRITE */

	spin_unlock_irq(&xd_lock);

	control = p->control;
	if (!xd_dma_buffer)
		xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
	while (count) {
		temp = count < xd_maxsectors ? count : xd_maxsectors;

		track = block / p->sectors;
		head = track % p->heads;
		cylinder = track / p->heads;
		sector = block % p->sectors;

#ifdef DEBUG_READWRITE
		printk("xd_readwrite: drive = %d, head = %d, cylinder = %d, sector = %d, count = %d\n",drive,head,cylinder,sector,temp);
#endif /* DEBUG_READWRITE */

		if (xd_dma_buffer) {
			mode = xd_setup_dma(operation == READ ? DMA_MODE_READ : DMA_MODE_WRITE,(u_char *)(xd_dma_buffer),temp * 0x200);
			real_buffer = &xd_dma_buffer;
			for (i=0; i < (temp * 0x200); i++)
				xd_dma_buffer[i] = buffer[i];
		}
		else
			real_buffer = &buffer;

		xd_build(cmdblk,operation == READ ? CMD_READ : CMD_WRITE,drive,head,cylinder,sector,temp & 0xFF,control);

		switch (xd_command(cmdblk,mode,(u_char *)(*real_buffer),(u_char *)(*real_buffer),sense,XD_TIMEOUT)) {
			case 1:
				printk("xd%c: %s timeout, recalibrating drive\n",'a'+drive,(operation == READ ? "read" : "write"));
				xd_recalibrate(drive);
				spin_lock_irq(&xd_lock);
				return -EIO;
			case 2:
				if (sense[0] & 0x30) {
					printk("xd%c: %s - ",'a'+drive,(operation == READ ? "reading" : "writing"));
					switch ((sense[0] & 0x30) >> 4) {
					case 0: printk("drive error, code = 0x%X",sense[0] & 0x0F);
						break;
					case 1: printk("controller error, code = 0x%X",sense[0] & 0x0F);
						break;
					case 2: printk("command error, code = 0x%X",sense[0] & 0x0F);
						break;
					case 3: printk("miscellaneous error, code = 0x%X",sense[0] & 0x0F);
						break;
					}
				}
				if (sense[0] & 0x80)
					printk(" - CHS = %d/%d/%d\n",((sense[2] & 0xC0) << 2) | sense[3],sense[1] & 0x1F,sense[2] & 0x3F);
				/*	reported drive number = (sense[1] & 0xE0) >> 5 */
				else
					printk(" - no valid disk address\n");
				spin_lock_irq(&xd_lock);
				return -EIO;
		}
		if (xd_dma_buffer)
			for (i=0; i < (temp * 0x200); i++)
				buffer[i] = xd_dma_buffer[i];

		count -= temp, buffer += temp * 0x200, block += temp;
	}
	spin_lock_irq(&xd_lock);
	return 0;
}

/* xd_recalibrate: recalibrate a given drive and reset controller if necessary */
static void xd_recalibrate (u_char drive)
{
	u_char cmdblk[6];
	
	xd_build(cmdblk,CMD_RECALIBRATE,drive,0,0,0,0,0);
	if (xd_command(cmdblk,PIO_MODE,NULL,NULL,NULL,XD_TIMEOUT * 8))
		printk("xd%c: warning! error recalibrating, controller may be unstable\n", 'a'+drive);
}

/* xd_interrupt_handler: interrupt service routine */
static irqreturn_t xd_interrupt_handler(int irq, void *dev_id)
{
	if (inb(XD_STATUS) & STAT_INTERRUPT) {							/* check if it was our device */
#ifdef DEBUG_OTHER
		printk("xd_interrupt_handler: interrupt detected\n");
#endif /* DEBUG_OTHER */
		outb(0,XD_CONTROL);								/* acknowledge interrupt */
		wake_up(&xd_wait_int);	/* and wake up sleeping processes */
		return IRQ_HANDLED;
	}
	else
		printk("xd: unexpected interrupt\n");
	return IRQ_NONE;
}

/* xd_setup_dma: set up the DMA controller for a data transfer */
static u_char xd_setup_dma (u_char mode,u_char *buffer,u_int count)
{
	unsigned long f;
	
	if (nodma)
		return (PIO_MODE);
	if (((unsigned long) buffer & 0xFFFF0000) != (((unsigned long) buffer + count) & 0xFFFF0000)) {
#ifdef DEBUG_OTHER
		printk("xd_setup_dma: using PIO, transfer overlaps 64k boundary\n");
#endif /* DEBUG_OTHER */
		return (PIO_MODE);
	}
	
	f=claim_dma_lock();
	disable_dma(xd_dma);
	clear_dma_ff(xd_dma);
	set_dma_mode(xd_dma,mode);
	set_dma_addr(xd_dma, (unsigned long) buffer);
	set_dma_count(xd_dma,count);
	
	release_dma_lock(f);

	return (DMA_MODE);			/* use DMA and INT */
}

/* xd_build: put stuff into an array in a format suitable for the controller */
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)
{
	cmdblk[0] = command;
	cmdblk[1] = ((drive & 0x07) << 5) | (head & 0x1F);
	cmdblk[2] = ((cylinder & 0x300) >> 2) | (sector & 0x3F);
	cmdblk[3] = cylinder & 0xFF;
	cmdblk[4] = count;
	cmdblk[5] = control;
	
	return (cmdblk);
}

static void xd_watchdog (unsigned long unused)
{
	xd_error = 1;
	wake_up(&xd_wait_int);
}

/* xd_waitport: waits until port & mask == flags or a timeout occurs. return 1 for a timeout */
static inline u_char xd_waitport (u_short port,u_char flags,u_char mask,u_long timeout)
{
	u_long expiry = jiffies + timeout;
	int success;

	xdc_busy = 1;
	while ((success = ((inb(port) & mask) != flags)) && time_before(jiffies, expiry))
		schedule_timeout_uninterruptible(1);
	xdc_busy = 0;
	return (success);
}

static inline u_int xd_wait_for_IRQ (void)
{
	unsigned long flags;
	xd_watchdog_int.expires = jiffies + 8 * HZ;
	add_timer(&xd_watchdog_int);
	
	flags=claim_dma_lock();
	enable_dma(xd_dma);
	release_dma_lock(flags);
	
	sleep_on(&xd_wait_int);
	del_timer(&xd_watchdog_int);
	xdc_busy = 0;
	
	flags=claim_dma_lock();
	disable_dma(xd_dma);
	release_dma_lock(flags);
	
	if (xd_error) {
		printk("xd: missed IRQ - command aborted\n");
		xd_error = 0;
		return (1);
	}
	return (0);
}

/* xd_command: handle all data transfers necessary for a single command */
static u_int xd_command (u_char *command,u_char mode,u_char *indata,u_char *outdata,u_char *sense,u_long timeout)
{
	u_char cmdblk[6],csb,complete = 0;

#ifdef DEBUG_COMMAND
	printk("xd_command: command = 0x%X, mode = 0x%X, indata = 0x%X, outdata = 0x%X, sense = 0x%X\n",command,mode,indata,outdata,sense);
#endif /* DEBUG_COMMAND */

	outb(0,XD_SELECT);
	outb(mode,XD_CONTROL);

	if (xd_waitport(XD_STATUS,STAT_SELECT,STAT_SELECT,timeout))
		return (1);

	while (!complete) {
		if (xd_waitport(XD_STATUS,STAT_READY,STAT_READY,timeout))
			return (1);

		switch (inb(XD_STATUS) & (STAT_COMMAND | STAT_INPUT)) {
			case 0:
				if (mode == DMA_MODE) {
					if (xd_wait_for_IRQ())
						return (1);
				} else
					outb(outdata ? *outdata++ : 0,XD_DATA);
				break;
			case STAT_INPUT:
				if (mode == DMA_MODE) {
					if (xd_wait_for_IRQ())
						return (1);
				} else
					if (indata)
						*indata++ = inb(XD_DATA);
					else
						inb(XD_DATA);
				break;
			case STAT_COMMAND:
				outb(command ? *command++ : 0,XD_DATA);
				break;
			case STAT_COMMAND | STAT_INPUT:
				complete = 1;
				break;
		}
	}
	csb = inb(XD_DATA);

	if (xd_waitport(XD_STATUS,0,STAT_SELECT,timeout))					/* wait until deselected */
		return (1);

	if (csb & CSB_ERROR) {									/* read sense data if error */
		xd_build(cmdblk,CMD_SENSE,(csb & CSB_LUN) >> 5,0,0,0,0,0);
		if (xd_command(cmdblk,0,sense,NULL,NULL,XD_TIMEOUT))
			printk("xd: warning! sense command failed!\n");
	}

#ifdef DEBUG_COMMAND
	printk("xd_command: completed with csb = 0x%X\n",csb);
#endif /* DEBUG_COMMAND */

	return (csb & CSB_ERROR);
}

static u_char __init xd_initdrives (void (*init_drive)(u_char drive))
{
	u_char cmdblk[6],i,count = 0;

	for (i = 0; i < XD_MAXDRIVES; i++) {
		xd_build(cmdblk,CMD_TESTREADY,i,0,0,0,0,0);
		if (!xd_command(cmdblk,PIO_MODE,NULL,NULL,NULL,XD_TIMEOUT*8)) {
			msleep_interruptible(XD_INIT_DISK_DELAY);

			init_drive(count);
			count++;

			msleep_interruptible(XD_INIT_DISK_DELAY);
		}
	}
	return (count);
}

static void __init xd_manual_geo_set (u_char drive)
{
	xd_info[drive].heads = (u_char)(xd_geo[3 * drive + 1]);
	xd_info[drive].cylinders = (u_short)(xd_geo[3 * drive]);
	xd_info[drive].sectors = (u_char)(xd_geo[3 * drive + 2]);
}

static void __init xd_dtc_init_controller (unsigned int address)
{
	switch (address) {
		case 0x00000:
		case 0xC8000:	break;			/*initial: 0x320 */
		case 0xCA000:	xd_iobase = 0x324; 
		case 0xD0000:				/*5150CX*/
		case 0xD8000:	break;			/*5150CX & 5150XL*/
		default:        printk("xd_dtc_init_controller: unsupported BIOS address %06x\n",address);
				break;
	}
	xd_maxsectors = 0x01;		/* my card seems to have trouble doing multi-block transfers? */

	outb(0,XD_RESET);		/* reset the controller */
}


static void __init xd_dtc5150cx_init_drive (u_char drive)
{
	/* values from controller's BIOS - BIOS chip may be removed */
	static u_short geometry_table[][4] = {
		{0x200,8,0x200,0x100},
		{0x267,2,0x267,0x267},
		{0x264,4,0x264,0x80},
		{0x132,4,0x132,0x0},
		{0x132,2,0x80, 0x132},
		{0x177,8,0x177,0x0},
		{0x132,8,0x84, 0x0},
		{},  /* not used */
		{0x132,6,0x80, 0x100},
		{0x200,6,0x100,0x100},
		{0x264,2,0x264,0x80},
		{0x280,4,0x280,0x100},
		{0x2B9,3,0x2B9,0x2B9},
		{0x2B9,5,0x2B9,0x2B9},
		{0x280,6,0x280,0x100},
		{0x132,4,0x132,0x0}};
	u_char n;

	n = inb(XD_JUMPER);
	n = (drive ? n : (n >> 2)) & 0x33;
	n = (n | (n >> 2)) & 0x0F;
	if (xd_geo[3*drive])
		xd_manual_geo_set(drive);
	else
		if (n != 7) {	
			xd_info[drive].heads = (u_char)(geometry_table[n][1]);			/* heads */
			xd_info[drive].cylinders = geometry_table[n][0];	/* cylinders */
			xd_info[drive].sectors = 17;				/* sectors */
#if 0
			xd_info[drive].rwrite = geometry_table[n][2];	/* reduced write */
			xd_info[drive].precomp = geometry_table[n][3]		/* write precomp */
			xd_info[drive].ecc = 0x0B;				/* ecc length */
#endif /* 0 */
		}
		else {
			printk("xd%c: undetermined drive geometry\n",'a'+drive);
			return;
		}
	xd_info[drive].control = 5;				/* control byte */
	xd_setparam(CMD_DTCSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,geometry_table[n][2],geometry_table[n][3],0x0B);
	xd_recalibrate(drive);
}

static void __init xd_dtc_init_drive (u_char drive)
{
	u_char cmdblk[6],buf[64];

	xd_build(cmdblk,CMD_DTCGETGEOM,drive,0,0,0,0,0);
	if (!xd_command(cmdblk,PIO_MODE,buf,NULL,NULL,XD_TIMEOUT * 2)) {
		xd_info[drive].heads = buf[0x0A];			/* heads */
		xd_info[drive].cylinders = ((u_short *) (buf))[0x04];	/* cylinders */
		xd_info[drive].sectors = 17;				/* sectors */
		if (xd_geo[3*drive])
			xd_manual_geo_set(drive);
#if 0
		xd_info[drive].rwrite = ((u_short *) (buf + 1))[0x05];	/* reduced write */
		xd_info[drive].precomp = ((u_short *) (buf + 1))[0x06];	/* write precomp */
		xd_info[drive].ecc = buf[0x0F];				/* ecc length */
#endif /* 0 */
		xd_info[drive].control = 0;				/* control byte */

		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]);
		xd_build(cmdblk,CMD_DTCSETSTEP,drive,0,0,0,0,7);
		if (xd_command(cmdblk,PIO_MODE,NULL,NULL,NULL,XD_TIMEOUT * 2))
			printk("xd_dtc_init_drive: error setting step rate for xd%c\n", 'a'+drive);
	}
	else
		printk("xd_dtc_init_drive: error reading geometry for xd%c\n", 'a'+drive);
}

static void __init xd_wd_init_controller (unsigned int address)
{
	switch (address) {
		case 0x00000:
		case 0xC8000:	break;			/*initial: 0x320 */
		case 0xCA000:	xd_iobase = 0x324; break;
		case 0xCC000:   xd_iobase = 0x328; break;
		case 0xCE000:   xd_iobase = 0x32C; break;
		case 0xD0000:	xd_iobase = 0x328; break; /* ? */
		case 0xD8000:	xd_iobase = 0x32C; break; /* ? */
		default:        printk("xd_wd_init_controller: unsupported BIOS address %06x\n",address);
				break;
	}
	xd_maxsectors = 0x01;		/* this one doesn't wrap properly either... */

	outb(0,XD_RESET);		/* reset the controller */

	msleep(XD_INIT_DISK_DELAY);
}

static void __init xd_wd_init_drive (u_char drive)
{
	/* values from controller's BIOS - BIOS may be disabled */
	static u_short geometry_table[][4] = {
		{0x264,4,0x1C2,0x1C2},   /* common part */
		{0x132,4,0x099,0x0},
		{0x267,2,0x1C2,0x1C2},
		{0x267,4,0x1C2,0x1C2},

		{0x334,6,0x335,0x335},   /* 1004 series RLL */
		{0x30E,4,0x30F,0x3DC},
		{0x30E,2,0x30F,0x30F},
		{0x267,4,0x268,0x268},

		{0x3D5,5,0x3D6,0x3D6},   /* 1002 series RLL */
		{0x3DB,7,0x3DC,0x3DC},
		{0x264,4,0x265,0x265},
		{0x267,4,0x268,0x268}};

	u_char cmdblk[6],buf[0x200];
	u_char n = 0,rll,jumper_state,use_jumper_geo;
	u_char wd_1002 = (xd_sigs[xd_type].string[7] == '6');
	
	jumper_state = ~(inb(0x322));
	if (jumper_state & 0x40)
		xd_irq = 9;
	rll = (jumper_state & 0x30) ? (0x04 << wd_1002) : 0;
	xd_build(cmdblk,CMD_READ,drive,0,0,0,1,0);
	if (!xd_command(cmdblk,PIO_MODE,buf,NULL,NULL,XD_TIMEOUT * 2)) {
		xd_info[drive].heads = buf[0x1AF];				/* heads */
		xd_info[drive].cylinders = ((u_short *) (buf + 1))[0xD6];	/* cylinders */
		xd_info[drive].sectors = 17;					/* sectors */
		if (xd_geo[3*drive])
			xd_manual_geo_set(drive);
#if 0
		xd_info[drive].rwrite = ((u_short *) (buf))[0xD8];		/* reduced write */
		xd_info[drive].wprecomp = ((u_short *) (buf))[0xDA];		/* write precomp */
		xd_info[drive].ecc = buf[0x1B4];				/* ecc length */
#endif /* 0 */
		xd_info[drive].control = buf[0x1B5];				/* control byte */
		use_jumper_geo = !(xd_info[drive].heads) || !(xd_info[drive].cylinders);
		if (xd_geo[3*drive]) {
			xd_manual_geo_set(drive);
			xd_info[drive].control = rll ? 7 : 5;
		}
		else if (use_jumper_geo) {
			n = (((jumper_state & 0x0F) >> (drive << 1)) & 0x03) | rll;
			xd_info[drive].cylinders = geometry_table[n][0];
			xd_info[drive].heads = (u_char)(geometry_table[n][1]);
			xd_info[drive].control = rll ? 7 : 5;
#if 0
			xd_info[drive].rwrite = geometry_table[n][2];
			xd_info[drive].wprecomp = geometry_table[n][3];
			xd_info[drive].ecc = 0x0B;
#endif /* 0 */
		}
		if (!wd_1002) {
			if (use_jumper_geo)
				xd_setparam(CMD_WDSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,
					geometry_table[n][2],geometry_table[n][3],0x0B);
			else
				xd_setparam(CMD_WDSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,
					((u_short *) (buf))[0xD8],((u_short *) (buf))[0xDA],buf[0x1B4]);
		}
	/* 1002 based RLL controller requests converted addressing, but reports physical 
	   (physical 26 sec., logical 17 sec.) 
	   1004 based ???? */
		if (rll & wd_1002) {
			if ((xd_info[drive].cylinders *= 26,
			     xd_info[drive].cylinders /= 17) > 1023)
				xd_info[drive].cylinders = 1023;  /* 1024 ? */
#if 0
			xd_info[drive].rwrite *= 26; 
			xd_info[drive].rwrite /= 17;
			xd_info[drive].wprecomp *= 26
			xd_info[drive].wprecomp /= 17;
#endif /* 0 */
		}
	}
	else
		printk("xd_wd_init_drive: error reading geometry for xd%c\n",'a'+drive);	

}

static void __init xd_seagate_init_controller (unsigned int address)
{
	switch (address) {
		case 0x00000:
		case 0xC8000:	break;			/*initial: 0x320 */
		case 0xD0000:	xd_iobase = 0x324; break;
		case 0xD8000:	xd_iobase = 0x328; break;
		case 0xE0000:	xd_iobase = 0x32C; break;
		default:	printk("xd_seagate_init_controller: unsupported BIOS address %06x\n",address);
				break;
	}
	xd_maxsectors = 0x40;

	outb(0,XD_RESET);		/* reset the controller */
}

static void __init xd_seagate_init_drive (u_char drive)
{
	u_char cmdblk[6],buf[0x200];

	xd_build(cmdblk,CMD_ST11GETGEOM,drive,0,0,0,1,0);
	if (!xd_command(cmdblk,PIO_MODE,buf,NULL,NULL,XD_TIMEOUT * 2)) {
		xd_info[drive].heads = buf[0x04];				/* heads */
		xd_info[drive].cylinders = (buf[0x02] << 8) | buf[0x03];	/* cylinders */
		xd_info[drive].sectors = buf[0x05];				/* sectors */
		xd_info[drive].control = 0;					/* control byte */
	}
	else
		printk("xd_seagate_init_drive: error reading geometry from xd%c\n", 'a'+drive);
}

/* Omti support courtesy Dirk Melchers */
static void __init xd_omti_init_controller (unsigned int address)
{
	switch (address) {
		case 0x00000:
		case 0xC8000:	break;			/*initial: 0x320 */
		case 0xD0000:	xd_iobase = 0x324; break;
		case 0xD8000:	xd_iobase = 0x328; break;
		case 0xE0000:	xd_iobase = 0x32C; break;
		default:	printk("xd_omti_init_controller: unsupported BIOS address %06x\n",address);
				break;
	}
	
	xd_maxsectors = 0x40;

	outb(0,XD_RESET);		/* reset the controller */
}

static void __init xd_omti_init_drive (u_char drive)
{
	/* gets infos from drive */
	xd_override_init_drive(drive);

	/* set other parameters, Hardcoded, not that nice :-) */
	xd_info[drive].control = 2;
}

/* Xebec support (AK) */
static void __init xd_xebec_init_controller (unsigned int address)
{
/* iobase may be set manually in range 0x300 - 0x33C
      irq may be set manually to 2(9),3,4,5,6,7
      dma may be set manually to 1,2,3
	(How to detect them ???)
BIOS address may be set manually in range 0x0 - 0xF8000
If you need non-standard settings use the xd=... command */

	switch (address) {
		case 0x00000:
		case 0xC8000:	/* initially: xd_iobase==0x320 */
		case 0xD0000:
		case 0xD2000:
		case 0xD4000:
		case 0xD6000:
		case 0xD8000:
		case 0xDA000:
		case 0xDC000:
		case 0xDE000:
		case 0xE0000:	break;
		default:	printk("xd_xebec_init_controller: unsupported BIOS address %06x\n",address);
				break;
		}

	xd_maxsectors = 0x01;
	outb(0,XD_RESET);		/* reset the controller */

	msleep(XD_INIT_DISK_DELAY);
}

static void __init xd_xebec_init_drive (u_char drive)
{
	/* values from controller's BIOS - BIOS chip may be removed */
	static u_short geometry_table[][5] = {
		{0x132,4,0x080,0x080,0x7},
		{0x132,4,0x080,0x080,0x17},
		{0x264,2,0x100,0x100,0x7},
		{0x264,2,0x100,0x100,0x17},
		{0x132,8,0x080,0x080,0x7},
		{0x132,8,0x080,0x080,0x17},
		{0x264,4,0x100,0x100,0x6},
		{0x264,4,0x100,0x100,0x17},
		{0x2BC,5,0x2BC,0x12C,0x6},
		{0x3A5,4,0x3A5,0x3A5,0x7},
		{0x26C,6,0x26C,0x26C,0x7},
		{0x200,8,0x200,0x100,0x17},
		{0x400,5,0x400,0x400,0x7},
		{0x400,6,0x400,0x400,0x7},
		{0x264,8,0x264,0x200,0x17},
		{0x33E,7,0x33E,0x200,0x7}};
	u_char n;

	n = inb(XD_JUMPER) & 0x0F; /* BIOS's drive number: same geometry 
					is assumed for BOTH drives */
	if (xd_geo[3*drive])
		xd_manual_geo_set(drive);
	else {
		xd_info[drive].heads = (u_char)(geometry_table[n][1]);			/* heads */
		xd_info[drive].cylinders = geometry_table[n][0];	/* cylinders */
		xd_info[drive].sectors = 17;				/* sectors */
#if 0
		xd_info[drive].rwrite = geometry_table[n][2];	/* reduced write */
		xd_info[drive].precomp = geometry_table[n][3]		/* write precomp */
		xd_info[drive].ecc = 0x0B;				/* ecc length */
#endif /* 0 */
	}
	xd_info[drive].control = geometry_table[n][4];			/* control byte */
	xd_setparam(CMD_XBSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,geometry_table[n][2],geometry_table[n][3],0x0B);
	xd_recalibrate(drive);
}

/* xd_override_init_drive: this finds disk geometry in a "binary search" style, narrowing in on the "correct" number of heads
   etc. by trying values until it gets the highest successful value. Idea courtesy Salvador Abreu (spa@fct.unl.pt). */
static void __init xd_override_init_drive (u_char drive)
{
	u_short min[] = { 0,0,0 },max[] = { 16,1024,64 },test[] = { 0,0,0 };
	u_char cmdblk[6],i;

	if (xd_geo[3*drive])
		xd_manual_geo_set(drive);
	else {
		for (i = 0; i < 3; i++) {
			while (min[i] != max[i] - 1) {
				test[i] = (min[i] + max[i]) / 2;
				xd_build(cmdblk,CMD_SEEK,drive,(u_char) test[0],(u_short) test[1],(u_char) test[2],0,0);
				if (!xd_command(cmdblk,PIO_MODE,NULL,NULL,NULL,XD_TIMEOUT * 2))
					min[i] = test[i];
				else
					max[i] = test[i];
			}
			test[i] = min[i];
		}
		xd_info[drive].heads = (u_char) min[0] + 1;
		xd_info[drive].cylinders = (u_short) min[1] + 1;
		xd_info[drive].sectors = (u_char) min[2] + 1;
	}
	xd_info[drive].control = 0;
}

/* xd_setup: initialise controller from command line parameters */
static void __init do_xd_setup (int *integers)
{
	switch (integers[0]) {
		case 4: if (integers[4] < 0)
				nodma = 1;
			else if (integers[4] < 8)
				xd_dma = integers[4];
		case 3: if ((integers[3] > 0) && (integers[3] <= 0x3FC))
				xd_iobase = integers[3];
		case 2: if ((integers[2] > 0) && (integers[2] < 16))
				xd_irq = integers[2];
		case 1: xd_override = 1;
			if ((integers[1] >= 0) && (integers[1] < ARRAY_SIZE(xd_sigs)))
				xd_type = integers[1];
		case 0: break;
		default:printk("xd: too many parameters for xd\n");
	}
	xd_maxsectors = 0x01;
}

/* xd_setparam: set the drive characteristics */
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)
{
	u_char cmdblk[14];

	xd_build(cmdblk,command,drive,0,0,0,0,0);
	cmdblk[6] = (u_char) (cylinders >> 8) & 0x03;
	cmdblk[7] = (u_char) (cylinders & 0xFF);
	cmdblk[8] = heads & 0x1F;
	cmdblk[9] = (u_char) (rwrite >> 8) & 0x03;
	cmdblk[10] = (u_char) (rwrite & 0xFF);
	cmdblk[11] = (u_char) (wprecomp >> 8) & 0x03;
	cmdblk[12] = (u_char) (wprecomp & 0xFF);
	cmdblk[13] = ecc;

	/* Some controllers require geometry info as data, not command */

	if (xd_command(cmdblk,PIO_MODE,NULL,&cmdblk[6],NULL,XD_TIMEOUT * 2))
		printk("xd: error setting characteristics for xd%c\n", 'a'+drive);
}


#ifdef MODULE

module_param_array(xd, int, NULL, 0);
module_param_array(xd_geo, int, NULL, 0);
module_param(nodma, bool, 0);

MODULE_LICENSE("GPL");

void cleanup_module(void)
{
	int i;
	unregister_blkdev(XT_DISK_MAJOR, "xd");
	for (i = 0; i < xd_drives; i++) {
		del_gendisk(xd_gendisk[i]);
		put_disk(xd_gendisk[i]);
	}
	blk_cleanup_queue(xd_queue);
	release_region(xd_iobase,4);
	if (xd_drives) {
		free_irq(xd_irq, NULL);
		free_dma(xd_dma);
		if (xd_dma_buffer)
			xd_dma_mem_free((unsigned long)xd_dma_buffer, xd_maxsectors * 0x200);
	}
}
#else

static int __init xd_setup (char *str)
{
	int ints[5];
	get_options (str, ARRAY_SIZE (ints), ints);
	do_xd_setup (ints);
	return 1;
}

/* xd_manual_geo_init: initialise drive geometry from command line parameters
   (used only for WD drives) */
static int __init xd_manual_geo_init (char *str)
{
	int i, integers[1 + 3*XD_MAXDRIVES];

	get_options (str, ARRAY_SIZE (integers), integers);
	if (integers[0]%3 != 0) {
		printk("xd: incorrect number of parameters for xd_geo\n");
		return 1;
	}
	for (i = 0; (i < integers[0]) && (i < 3*XD_MAXDRIVES); i++)
		xd_geo[i] = integers[i+1];
	return 1;
}

__setup ("xd=", xd_setup);
__setup ("xd_geo=", xd_manual_geo_init);

#endif /* MODULE */

module_init(xd_init);
MODULE_ALIAS_BLOCKDEV_MAJOR(XT_DISK_MAJOR);
