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