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