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