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