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