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