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