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