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