commented early_printk patch because of rejects.
[linux-flexiantxendom0-3.2.10.git] / drivers / block / xd.c
1 /*
2  * This file contains the driver for an XT hard disk controller
3  * (at least the DTC 5150X) for Linux.
4  *
5  * Author: Pat Mackinlay, pat@it.com.au
6  * Date: 29/09/92
7  * 
8  * Revised: 01/01/93, ...
9  *
10  * Ref: DTC 5150X Controller Specification (thanks to Kevin Fowler,
11  *   kevinf@agora.rain.com)
12  * Also thanks to: Salvador Abreu, Dave Thaler, Risto Kankkunen and
13  *   Wim Van Dorst.
14  *
15  * Revised: 04/04/94 by Risto Kankkunen
16  *   Moved the detection code from xd_init() to xd_geninit() as it needed
17  *   interrupts enabled and Linus didn't want to enable them in that first
18  *   phase. xd_geninit() is the place to do these kinds of things anyway,
19  *   he says.
20  *
21  * Modularized: 04/10/96 by Todd Fries, tfries@umr.edu
22  *
23  * Revised: 13/12/97 by Andrzej Krzysztofowicz, ankry@mif.pg.gda.pl
24  *   Fixed some problems with disk initialization and module initiation.
25  *   Added support for manual geometry setting (except Seagate controllers)
26  *   in form:
27  *      xd_geo=<cyl_xda>,<head_xda>,<sec_xda>[,<cyl_xdb>,<head_xdb>,<sec_xdb>]
28  *   Recovered DMA access. Abridged messages. Added support for DTC5051CX,
29  *   WD1002-27X & XEBEC controllers. Driver uses now some jumper settings.
30  *   Extended ioctl() support.
31  *
32  * Bugfix: 15/02/01, Paul G. - inform queue layer of tiny xd_maxsect.
33  *
34  */
35
36 #include <linux/module.h>
37 #include <linux/errno.h>
38 #include <linux/interrupt.h>
39 #include <linux/mm.h>
40 #include <linux/fs.h>
41 #include <linux/kernel.h>
42 #include <linux/timer.h>
43 #include <linux/genhd.h>
44 #include <linux/hdreg.h>
45 #include <linux/ioport.h>
46 #include <linux/init.h>
47 #include <linux/wait.h>
48 #include <linux/devfs_fs_kernel.h>
49 #include <linux/blkdev.h>
50 #include <linux/blkpg.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*HZ/1000)  /* 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 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 = 0;
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 spinlock_t xd_lock = SPIN_LOCK_UNLOCKED;
128
129 static struct gendisk *xd_gendisk[2];
130
131 static struct block_device_operations xd_fops = {
132         .owner  = THIS_MODULE,
133         .ioctl  = xd_ioctl,
134 };
135 static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int);
136 static u_char xd_drives, xd_irq = 5, xd_dma = 3, xd_maxsectors;
137 static u_char xd_override __initdata = 0, xd_type __initdata = 0;
138 static u_short xd_iobase = 0x320;
139 static int xd_geo[XD_MAXDRIVES*3] __initdata = { 0, };
140
141 static volatile int xdc_busy;
142 static struct timer_list xd_watchdog_int;
143
144 static volatile u_char xd_error;
145 static int nodma = XD_DONT_USE_DMA;
146
147 static struct request_queue *xd_queue;
148
149 /* xd_init: register the block device number and set up pointer tables */
150 static int __init xd_init(void)
151 {
152         u_char i,controller;
153         unsigned int address;
154         int err;
155
156 #ifdef MODULE
157         {
158                 u_char count = 0;
159                 for (i = 4; i > 0; i--)
160                         if (((xd[i] = xd[i-1]) >= 0) && !count)
161                                 count = i;
162                 if ((xd[0] = count))
163                         do_xd_setup(xd);
164         }
165 #endif
166
167         init_timer (&xd_watchdog_int); xd_watchdog_int.function = xd_watchdog;
168
169         if (!xd_dma_buffer)
170                 xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
171         if (!xd_dma_buffer) {
172                 printk(KERN_ERR "xd: Out of memory.\n");
173                 return -ENOMEM;
174         }
175
176         err = -EBUSY;
177         if (register_blkdev(XT_DISK_MAJOR, "xd"))
178                 goto out1;
179
180         err = -ENOMEM;
181         xd_queue = blk_init_queue(do_xd_request, &xd_lock);
182         if (!xd_queue)
183                 goto out1a;
184
185         devfs_mk_dir("xd");
186         if (xd_detect(&controller,&address)) {
187
188                 printk("Detected a%s controller (type %d) at address %06x\n",
189                         xd_sigs[controller].name,controller,address);
190                 if (!request_region(xd_iobase,4,"xd")) {
191                         printk("xd: Ports at 0x%x are not available\n",
192                                 xd_iobase);
193                         goto out2;
194                 }
195                 if (controller)
196                         xd_sigs[controller].init_controller(address);
197                 xd_drives = xd_initdrives(xd_sigs[controller].init_drive);
198                 
199                 printk("Detected %d hard drive%s (using IRQ%d & DMA%d)\n",
200                         xd_drives,xd_drives == 1 ? "" : "s",xd_irq,xd_dma);
201         }
202
203         err = -ENODEV;
204         if (!xd_drives)
205                 goto out3;
206
207         for (i = 0; i < xd_drives; i++) {
208                 XD_INFO *p = &xd_info[i];
209                 struct gendisk *disk = alloc_disk(64);
210                 if (!disk)
211                         goto Enomem;
212                 p->unit = i;
213                 disk->major = XT_DISK_MAJOR;
214                 disk->first_minor = i<<6;
215                 sprintf(disk->disk_name, "xd%c", i+'a');
216                 disk->fops = &xd_fops;
217                 disk->private_data = p;
218                 disk->queue = xd_queue;
219                 set_capacity(disk, p->heads * p->cylinders * p->sectors);
220                 printk(" %s: CHS=%d/%d/%d\n", disk->disk_name,
221                         p->cylinders, p->heads, p->sectors);
222                 xd_gendisk[i] = disk;
223         }
224
225         err = -EBUSY;
226         if (request_irq(xd_irq,xd_interrupt_handler, 0, "XT hard disk", NULL)) {
227                 printk("xd: unable to get IRQ%d\n",xd_irq);
228                 goto out4;
229         }
230
231         if (request_dma(xd_dma,"xd")) {
232                 printk("xd: unable to get DMA%d\n",xd_dma);
233                 goto out5;
234         }
235
236         /* xd_maxsectors depends on controller - so set after detection */
237         blk_queue_max_sectors(xd_queue, xd_maxsectors);
238
239         for (i = 0; i < xd_drives; i++)
240                 add_disk(xd_gendisk[i]);
241
242         return 0;
243
244 out5:
245         free_irq(xd_irq, NULL);
246 out4:
247         for (i = 0; i < xd_drives; i++)
248                 put_disk(xd_gendisk[i]);
249 out3:
250         release_region(xd_iobase,4);
251 out2:
252         devfs_remove("xd");
253         blk_cleanup_queue(xd_queue);
254 out1a:
255         unregister_blkdev(XT_DISK_MAJOR, "xd");
256 out1:
257         if (xd_dma_buffer)
258                 xd_dma_mem_free((unsigned long)xd_dma_buffer,
259                                 xd_maxsectors * 0x200);
260         return err;
261 Enomem:
262         err = -ENOMEM;
263         while (i--)
264                 put_disk(xd_gendisk[i]);
265         goto out3;
266 }
267
268 /* xd_detect: scan the possible BIOS ROM locations for the signature strings */
269 static u_char __init xd_detect (u_char *controller, unsigned int *address)
270 {
271         u_char i,j,found = 0;
272
273         if (xd_override)
274         {
275                 *controller = xd_type;
276                 *address = 0;
277                 return(1);
278         }
279
280         for (i = 0; i < (sizeof(xd_bases) / sizeof(xd_bases[0])) && !found; i++)
281                 for (j = 1; j < (sizeof(xd_sigs) / sizeof(xd_sigs[0])) && !found; j++)
282                         if (isa_check_signature(xd_bases[i] + xd_sigs[j].offset,xd_sigs[j].string,strlen(xd_sigs[j].string))) {
283                                 *controller = j;
284                                 xd_type = j;
285                                 *address = xd_bases[i];
286                                 found++;
287                         }
288         return (found);
289 }
290
291 /* do_xd_request: handle an incoming request */
292 static void do_xd_request (request_queue_t * q)
293 {
294         struct request *req;
295
296         if (xdc_busy)
297                 return;
298
299         while ((req = elv_next_request(q)) != NULL) {
300                 unsigned block = req->sector;
301                 unsigned count = req->nr_sectors;
302                 int rw = rq_data_dir(req);
303                 XD_INFO *disk = req->rq_disk->private_data;
304                 int res = 0;
305                 int retry;
306
307                 if (!(req->flags & REQ_CMD)) {
308                         end_request(req, 0);
309                         continue;
310                 }
311                 if (block + count > get_capacity(req->rq_disk)) {
312                         end_request(req, 0);
313                         continue;
314                 }
315                 if (rw != READ && rw != WRITE) {
316                         printk("do_xd_request: unknown request\n");
317                         end_request(req, 0);
318                         continue;
319                 }
320                 for (retry = 0; (retry < XD_RETRIES) && !res; retry++)
321                         res = xd_readwrite(rw, disk, req->buffer, block, count);
322                 end_request(req, res);  /* wrap up, 0 = fail, 1 = success */
323         }
324 }
325
326 /* xd_ioctl: handle device ioctl's */
327 static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg)
328 {
329         XD_INFO *p = inode->i_bdev->bd_disk->private_data;
330
331         switch (cmd) {
332                 case HDIO_GETGEO:
333                 {
334                         struct hd_geometry g;
335                         struct hd_geometry *geometry = (struct hd_geometry *) arg;
336                         g.heads = p->heads;
337                         g.sectors = p->sectors;
338                         g.cylinders = p->cylinders;
339                         g.start = get_start_sect(inode->i_bdev);
340                         return copy_to_user(geometry, &g, sizeof g) ? -EFAULT : 0;
341                 }
342                 case HDIO_SET_DMA:
343                         if (!capable(CAP_SYS_ADMIN)) return -EACCES;
344                         if (xdc_busy) return -EBUSY;
345                         nodma = !arg;
346                         if (nodma && xd_dma_buffer) {
347                                 xd_dma_mem_free((unsigned long)xd_dma_buffer,
348                                                 xd_maxsectors * 0x200);
349                                 xd_dma_buffer = 0;
350                         } else if (!nodma && !xd_dma_buffer) {
351                                 xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
352                                 if (!xd_dma_buffer) {
353                                         nodma = XD_DONT_USE_DMA;
354                                         return -ENOMEM;
355                                 }
356                         }
357                         return 0;
358                 case HDIO_GET_DMA:
359                         return put_user(!nodma, (long *) arg);
360                 case HDIO_GET_MULTCOUNT:
361                         return put_user(xd_maxsectors, (long *) arg);
362                 default:
363                         return -EINVAL;
364         }
365 }
366
367 /* xd_readwrite: handle a read/write request */
368 static int xd_readwrite (u_char operation,XD_INFO *p,char *buffer,u_int block,u_int count)
369 {
370         int drive = p->unit;
371         u_char cmdblk[6],sense[4];
372         u_short track,cylinder;
373         u_char head,sector,control,mode = PIO_MODE,temp;
374         char **real_buffer;
375         register int i;
376         
377 #ifdef DEBUG_READWRITE
378         printk("xd_readwrite: operation = %s, drive = %d, buffer = 0x%X, block = %d, count = %d\n",operation == READ ? "read" : "write",drive,buffer,block,count);
379 #endif /* DEBUG_READWRITE */
380
381         spin_unlock_irq(&xd_lock);
382
383         control = p->control;
384         if (!xd_dma_buffer)
385                 xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
386         while (count) {
387                 temp = count < xd_maxsectors ? count : xd_maxsectors;
388
389                 track = block / p->sectors;
390                 head = track % p->heads;
391                 cylinder = track / p->heads;
392                 sector = block % p->sectors;
393
394 #ifdef DEBUG_READWRITE
395                 printk("xd_readwrite: drive = %d, head = %d, cylinder = %d, sector = %d, count = %d\n",drive,head,cylinder,sector,temp);
396 #endif /* DEBUG_READWRITE */
397
398                 if (xd_dma_buffer) {
399                         mode = xd_setup_dma(operation == READ ? DMA_MODE_READ : DMA_MODE_WRITE,(u_char *)(xd_dma_buffer),temp * 0x200);
400                         real_buffer = &xd_dma_buffer;
401                         for (i=0; i < (temp * 0x200); i++)
402                                 xd_dma_buffer[i] = buffer[i];
403                 }
404                 else
405                         real_buffer = &buffer;
406
407                 xd_build(cmdblk,operation == READ ? CMD_READ : CMD_WRITE,drive,head,cylinder,sector,temp & 0xFF,control);
408
409                 switch (xd_command(cmdblk,mode,(u_char *)(*real_buffer),(u_char *)(*real_buffer),sense,XD_TIMEOUT)) {
410                         case 1:
411                                 printk("xd%c: %s timeout, recalibrating drive\n",'a'+drive,(operation == READ ? "read" : "write"));
412                                 xd_recalibrate(drive);
413                                 spin_lock_irq(&xd_lock);
414                                 return (0);
415                         case 2:
416                                 if (sense[0] & 0x30) {
417                                         printk("xd%c: %s - ",'a'+drive,(operation == READ ? "reading" : "writing"));
418                                         switch ((sense[0] & 0x30) >> 4) {
419                                         case 0: printk("drive error, code = 0x%X",sense[0] & 0x0F);
420                                                 break;
421                                         case 1: printk("controller error, code = 0x%X",sense[0] & 0x0F);
422                                                 break;
423                                         case 2: printk("command error, code = 0x%X",sense[0] & 0x0F);
424                                                 break;
425                                         case 3: printk("miscellaneous error, code = 0x%X",sense[0] & 0x0F);
426                                                 break;
427                                         }
428                                 }
429                                 if (sense[0] & 0x80)
430                                         printk(" - CHS = %d/%d/%d\n",((sense[2] & 0xC0) << 2) | sense[3],sense[1] & 0x1F,sense[2] & 0x3F);
431                                 /*      reported drive number = (sense[1] & 0xE0) >> 5 */
432                                 else
433                                         printk(" - no valid disk address\n");
434                                 spin_lock_irq(&xd_lock);
435                                 return (0);
436                 }
437                 if (xd_dma_buffer)
438                         for (i=0; i < (temp * 0x200); i++)
439                                 buffer[i] = xd_dma_buffer[i];
440
441                 count -= temp, buffer += temp * 0x200, block += temp;
442         }
443         spin_lock_irq(&xd_lock);
444         return (1);
445 }
446
447 /* xd_recalibrate: recalibrate a given drive and reset controller if necessary */
448 static void xd_recalibrate (u_char drive)
449 {
450         u_char cmdblk[6];
451         
452         xd_build(cmdblk,CMD_RECALIBRATE,drive,0,0,0,0,0);
453         if (xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 8))
454                 printk("xd%c: warning! error recalibrating, controller may be unstable\n", 'a'+drive);
455 }
456
457 /* xd_interrupt_handler: interrupt service routine */
458 static irqreturn_t xd_interrupt_handler(int irq, void *dev_id,
459                                         struct pt_regs *regs)
460 {
461         if (inb(XD_STATUS) & STAT_INTERRUPT) {                                                  /* check if it was our device */
462 #ifdef DEBUG_OTHER
463                 printk("xd_interrupt_handler: interrupt detected\n");
464 #endif /* DEBUG_OTHER */
465                 outb(0,XD_CONTROL);                                                             /* acknowledge interrupt */
466                 wake_up(&xd_wait_int);  /* and wake up sleeping processes */
467                 return IRQ_HANDLED;
468         }
469         else
470                 printk("xd: unexpected interrupt\n");
471         return IRQ_NONE;
472 }
473
474 /* xd_setup_dma: set up the DMA controller for a data transfer */
475 static u_char xd_setup_dma (u_char mode,u_char *buffer,u_int count)
476 {
477         unsigned long f;
478         
479         if (nodma)
480                 return (PIO_MODE);
481         if (((unsigned long) buffer & 0xFFFF0000) != (((unsigned long) buffer + count) & 0xFFFF0000)) {
482 #ifdef DEBUG_OTHER
483                 printk("xd_setup_dma: using PIO, transfer overlaps 64k boundary\n");
484 #endif /* DEBUG_OTHER */
485                 return (PIO_MODE);
486         }
487         
488         f=claim_dma_lock();
489         disable_dma(xd_dma);
490         clear_dma_ff(xd_dma);
491         set_dma_mode(xd_dma,mode);
492         set_dma_addr(xd_dma, (unsigned long) buffer);
493         set_dma_count(xd_dma,count);
494         
495         release_dma_lock(f);
496
497         return (DMA_MODE);                      /* use DMA and INT */
498 }
499
500 /* xd_build: put stuff into an array in a format suitable for the controller */
501 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)
502 {
503         cmdblk[0] = command;
504         cmdblk[1] = ((drive & 0x07) << 5) | (head & 0x1F);
505         cmdblk[2] = ((cylinder & 0x300) >> 2) | (sector & 0x3F);
506         cmdblk[3] = cylinder & 0xFF;
507         cmdblk[4] = count;
508         cmdblk[5] = control;
509         
510         return (cmdblk);
511 }
512
513 static void xd_watchdog (unsigned long unused)
514 {
515         xd_error = 1;
516         wake_up(&xd_wait_int);
517 }
518
519 /* xd_waitport: waits until port & mask == flags or a timeout occurs. return 1 for a timeout */
520 static inline u_char xd_waitport (u_short port,u_char flags,u_char mask,u_long timeout)
521 {
522         u_long expiry = jiffies + timeout;
523         int success;
524
525         xdc_busy = 1;
526         while ((success = ((inb(port) & mask) != flags)) && time_before(jiffies, expiry)) {
527                 set_current_state(TASK_UNINTERRUPTIBLE);
528                 schedule_timeout(1);
529         }
530         xdc_busy = 0;
531         return (success);
532 }
533
534 static inline u_int xd_wait_for_IRQ (void)
535 {
536         unsigned long flags;
537         xd_watchdog_int.expires = jiffies + 8 * HZ;
538         add_timer(&xd_watchdog_int);
539         
540         flags=claim_dma_lock();
541         enable_dma(xd_dma);
542         release_dma_lock(flags);
543         
544         sleep_on(&xd_wait_int);
545         del_timer(&xd_watchdog_int);
546         xdc_busy = 0;
547         
548         flags=claim_dma_lock();
549         disable_dma(xd_dma);
550         release_dma_lock(flags);
551         
552         if (xd_error) {
553                 printk("xd: missed IRQ - command aborted\n");
554                 xd_error = 0;
555                 return (1);
556         }
557         return (0);
558 }
559
560 /* xd_command: handle all data transfers necessary for a single command */
561 static u_int xd_command (u_char *command,u_char mode,u_char *indata,u_char *outdata,u_char *sense,u_long timeout)
562 {
563         u_char cmdblk[6],csb,complete = 0;
564
565 #ifdef DEBUG_COMMAND
566         printk("xd_command: command = 0x%X, mode = 0x%X, indata = 0x%X, outdata = 0x%X, sense = 0x%X\n",command,mode,indata,outdata,sense);
567 #endif /* DEBUG_COMMAND */
568
569         outb(0,XD_SELECT);
570         outb(mode,XD_CONTROL);
571
572         if (xd_waitport(XD_STATUS,STAT_SELECT,STAT_SELECT,timeout))
573                 return (1);
574
575         while (!complete) {
576                 if (xd_waitport(XD_STATUS,STAT_READY,STAT_READY,timeout))
577                         return (1);
578
579                 switch (inb(XD_STATUS) & (STAT_COMMAND | STAT_INPUT)) {
580                         case 0:
581                                 if (mode == DMA_MODE) {
582                                         if (xd_wait_for_IRQ())
583                                                 return (1);
584                                 } else
585                                         outb(outdata ? *outdata++ : 0,XD_DATA);
586                                 break;
587                         case STAT_INPUT:
588                                 if (mode == DMA_MODE) {
589                                         if (xd_wait_for_IRQ())
590                                                 return (1);
591                                 } else
592                                         if (indata)
593                                                 *indata++ = inb(XD_DATA);
594                                         else
595                                                 inb(XD_DATA);
596                                 break;
597                         case STAT_COMMAND:
598                                 outb(command ? *command++ : 0,XD_DATA);
599                                 break;
600                         case STAT_COMMAND | STAT_INPUT:
601                                 complete = 1;
602                                 break;
603                 }
604         }
605         csb = inb(XD_DATA);
606
607         if (xd_waitport(XD_STATUS,0,STAT_SELECT,timeout))                                       /* wait until deselected */
608                 return (1);
609
610         if (csb & CSB_ERROR) {                                                                  /* read sense data if error */
611                 xd_build(cmdblk,CMD_SENSE,(csb & CSB_LUN) >> 5,0,0,0,0,0);
612                 if (xd_command(cmdblk,0,sense,0,0,XD_TIMEOUT))
613                         printk("xd: warning! sense command failed!\n");
614         }
615
616 #ifdef DEBUG_COMMAND
617         printk("xd_command: completed with csb = 0x%X\n",csb);
618 #endif /* DEBUG_COMMAND */
619
620         return (csb & CSB_ERROR);
621 }
622
623 static u_char __init xd_initdrives (void (*init_drive)(u_char drive))
624 {
625         u_char cmdblk[6],i,count = 0;
626
627         for (i = 0; i < XD_MAXDRIVES; i++) {
628                 xd_build(cmdblk,CMD_TESTREADY,i,0,0,0,0,0);
629                 if (!xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 8)) {
630                         set_current_state(TASK_INTERRUPTIBLE);
631                         schedule_timeout(XD_INIT_DISK_DELAY);
632
633                         init_drive(count);
634                         count++;
635
636                         set_current_state(TASK_INTERRUPTIBLE);
637                         schedule_timeout(XD_INIT_DISK_DELAY);
638                 }
639         }
640         return (count);
641 }
642
643 static void __init xd_manual_geo_set (u_char drive)
644 {
645         xd_info[drive].heads = (u_char)(xd_geo[3 * drive + 1]);
646         xd_info[drive].cylinders = (u_short)(xd_geo[3 * drive]);
647         xd_info[drive].sectors = (u_char)(xd_geo[3 * drive + 2]);
648 }
649
650 static void __init xd_dtc_init_controller (unsigned int address)
651 {
652         switch (address) {
653                 case 0x00000:
654                 case 0xC8000:   break;                  /*initial: 0x320 */
655                 case 0xCA000:   xd_iobase = 0x324; 
656                 case 0xD0000:                           /*5150CX*/
657                 case 0xD8000:   break;                  /*5150CX & 5150XL*/
658                 default:        printk("xd_dtc_init_controller: unsupported BIOS address %06x\n",address);
659                                 break;
660         }
661         xd_maxsectors = 0x01;           /* my card seems to have trouble doing multi-block transfers? */
662
663         outb(0,XD_RESET);               /* reset the controller */
664 }
665
666
667 static void __init xd_dtc5150cx_init_drive (u_char drive)
668 {
669         /* values from controller's BIOS - BIOS chip may be removed */
670         static u_short geometry_table[][4] = {
671                 {0x200,8,0x200,0x100},
672                 {0x267,2,0x267,0x267},
673                 {0x264,4,0x264,0x80},
674                 {0x132,4,0x132,0x0},
675                 {0x132,2,0x80, 0x132},
676                 {0x177,8,0x177,0x0},
677                 {0x132,8,0x84, 0x0},
678                 {},  /* not used */
679                 {0x132,6,0x80, 0x100},
680                 {0x200,6,0x100,0x100},
681                 {0x264,2,0x264,0x80},
682                 {0x280,4,0x280,0x100},
683                 {0x2B9,3,0x2B9,0x2B9},
684                 {0x2B9,5,0x2B9,0x2B9},
685                 {0x280,6,0x280,0x100},
686                 {0x132,4,0x132,0x0}};
687         u_char n;
688
689         n = inb(XD_JUMPER);
690         n = (drive ? n : (n >> 2)) & 0x33;
691         n = (n | (n >> 2)) & 0x0F;
692         if (xd_geo[3*drive])
693                 xd_manual_geo_set(drive);
694         else
695                 if (n != 7) {   
696                         xd_info[drive].heads = (u_char)(geometry_table[n][1]);                  /* heads */
697                         xd_info[drive].cylinders = geometry_table[n][0];        /* cylinders */
698                         xd_info[drive].sectors = 17;                            /* sectors */
699 #if 0
700                         xd_info[drive].rwrite = geometry_table[n][2];   /* reduced write */
701                         xd_info[drive].precomp = geometry_table[n][3]           /* write precomp */
702                         xd_info[drive].ecc = 0x0B;                              /* ecc length */
703 #endif /* 0 */
704                 }
705                 else {
706                         printk("xd%c: undetermined drive geometry\n",'a'+drive);
707                         return;
708                 }
709         xd_info[drive].control = 5;                             /* control byte */
710         xd_setparam(CMD_DTCSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,geometry_table[n][2],geometry_table[n][3],0x0B);
711         xd_recalibrate(drive);
712 }
713
714 static void __init xd_dtc_init_drive (u_char drive)
715 {
716         u_char cmdblk[6],buf[64];
717
718         xd_build(cmdblk,CMD_DTCGETGEOM,drive,0,0,0,0,0);
719         if (!xd_command(cmdblk,PIO_MODE,buf,0,0,XD_TIMEOUT * 2)) {
720                 xd_info[drive].heads = buf[0x0A];                       /* heads */
721                 xd_info[drive].cylinders = ((u_short *) (buf))[0x04];   /* cylinders */
722                 xd_info[drive].sectors = 17;                            /* sectors */
723                 if (xd_geo[3*drive])
724                         xd_manual_geo_set(drive);
725 #if 0
726                 xd_info[drive].rwrite = ((u_short *) (buf + 1))[0x05];  /* reduced write */
727                 xd_info[drive].precomp = ((u_short *) (buf + 1))[0x06]; /* write precomp */
728                 xd_info[drive].ecc = buf[0x0F];                         /* ecc length */
729 #endif /* 0 */
730                 xd_info[drive].control = 0;                             /* control byte */
731
732                 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]);
733                 xd_build(cmdblk,CMD_DTCSETSTEP,drive,0,0,0,0,7);
734                 if (xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 2))
735                         printk("xd_dtc_init_drive: error setting step rate for xd%c\n", 'a'+drive);
736         }
737         else
738                 printk("xd_dtc_init_drive: error reading geometry for xd%c\n", 'a'+drive);
739 }
740
741 static void __init xd_wd_init_controller (unsigned int address)
742 {
743         switch (address) {
744                 case 0x00000:
745                 case 0xC8000:   break;                  /*initial: 0x320 */
746                 case 0xCA000:   xd_iobase = 0x324; break;
747                 case 0xCC000:   xd_iobase = 0x328; break;
748                 case 0xCE000:   xd_iobase = 0x32C; break;
749                 case 0xD0000:   xd_iobase = 0x328; break; /* ? */
750                 case 0xD8000:   xd_iobase = 0x32C; break; /* ? */
751                 default:        printk("xd_wd_init_controller: unsupported BIOS address %06x\n",address);
752                                 break;
753         }
754         xd_maxsectors = 0x01;           /* this one doesn't wrap properly either... */
755
756         outb(0,XD_RESET);               /* reset the controller */
757
758         set_current_state(TASK_UNINTERRUPTIBLE);
759         schedule_timeout(XD_INIT_DISK_DELAY);
760 }
761
762 static void __init xd_wd_init_drive (u_char drive)
763 {
764         /* values from controller's BIOS - BIOS may be disabled */
765         static u_short geometry_table[][4] = {
766                 {0x264,4,0x1C2,0x1C2},   /* common part */
767                 {0x132,4,0x099,0x0},
768                 {0x267,2,0x1C2,0x1C2},
769                 {0x267,4,0x1C2,0x1C2},
770
771                 {0x334,6,0x335,0x335},   /* 1004 series RLL */
772                 {0x30E,4,0x30F,0x3DC},
773                 {0x30E,2,0x30F,0x30F},
774                 {0x267,4,0x268,0x268},
775
776                 {0x3D5,5,0x3D6,0x3D6},   /* 1002 series RLL */
777                 {0x3DB,7,0x3DC,0x3DC},
778                 {0x264,4,0x265,0x265},
779                 {0x267,4,0x268,0x268}};
780
781         u_char cmdblk[6],buf[0x200];
782         u_char n = 0,rll,jumper_state,use_jumper_geo;
783         u_char wd_1002 = (xd_sigs[xd_type].string[7] == '6');
784         
785         jumper_state = ~(inb(0x322));
786         if (jumper_state & 0x40)
787                 xd_irq = 9;
788         rll = (jumper_state & 0x30) ? (0x04 << wd_1002) : 0;
789         xd_build(cmdblk,CMD_READ,drive,0,0,0,1,0);
790         if (!xd_command(cmdblk,PIO_MODE,buf,0,0,XD_TIMEOUT * 2)) {
791                 xd_info[drive].heads = buf[0x1AF];                              /* heads */
792                 xd_info[drive].cylinders = ((u_short *) (buf + 1))[0xD6];       /* cylinders */
793                 xd_info[drive].sectors = 17;                                    /* sectors */
794                 if (xd_geo[3*drive])
795                         xd_manual_geo_set(drive);
796 #if 0
797                 xd_info[drive].rwrite = ((u_short *) (buf))[0xD8];              /* reduced write */
798                 xd_info[drive].wprecomp = ((u_short *) (buf))[0xDA];            /* write precomp */
799                 xd_info[drive].ecc = buf[0x1B4];                                /* ecc length */
800 #endif /* 0 */
801                 xd_info[drive].control = buf[0x1B5];                            /* control byte */
802                 use_jumper_geo = !(xd_info[drive].heads) || !(xd_info[drive].cylinders);
803                 if (xd_geo[3*drive]) {
804                         xd_manual_geo_set(drive);
805                         xd_info[drive].control = rll ? 7 : 5;
806                 }
807                 else if (use_jumper_geo) {
808                         n = (((jumper_state & 0x0F) >> (drive << 1)) & 0x03) | rll;
809                         xd_info[drive].cylinders = geometry_table[n][0];
810                         xd_info[drive].heads = (u_char)(geometry_table[n][1]);
811                         xd_info[drive].control = rll ? 7 : 5;
812 #if 0
813                         xd_info[drive].rwrite = geometry_table[n][2];
814                         xd_info[drive].wprecomp = geometry_table[n][3];
815                         xd_info[drive].ecc = 0x0B;
816 #endif /* 0 */
817                 }
818                 if (!wd_1002) {
819                         if (use_jumper_geo)
820                                 xd_setparam(CMD_WDSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,
821                                         geometry_table[n][2],geometry_table[n][3],0x0B);
822                         else
823                                 xd_setparam(CMD_WDSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,
824                                         ((u_short *) (buf))[0xD8],((u_short *) (buf))[0xDA],buf[0x1B4]);
825                 }
826         /* 1002 based RLL controller requests converted addressing, but reports physical 
827            (physical 26 sec., logical 17 sec.) 
828            1004 based ???? */
829                 if (rll & wd_1002) {
830                         if ((xd_info[drive].cylinders *= 26,
831                              xd_info[drive].cylinders /= 17) > 1023)
832                                 xd_info[drive].cylinders = 1023;  /* 1024 ? */
833 #if 0
834                         xd_info[drive].rwrite *= 26; 
835                         xd_info[drive].rwrite /= 17;
836                         xd_info[drive].wprecomp *= 26
837                         xd_info[drive].wprecomp /= 17;
838 #endif /* 0 */
839                 }
840         }
841         else
842                 printk("xd_wd_init_drive: error reading geometry for xd%c\n",'a'+drive);        
843
844 }
845
846 static void __init xd_seagate_init_controller (unsigned int address)
847 {
848         switch (address) {
849                 case 0x00000:
850                 case 0xC8000:   break;                  /*initial: 0x320 */
851                 case 0xD0000:   xd_iobase = 0x324; break;
852                 case 0xD8000:   xd_iobase = 0x328; break;
853                 case 0xE0000:   xd_iobase = 0x32C; break;
854                 default:        printk("xd_seagate_init_controller: unsupported BIOS address %06x\n",address);
855                                 break;
856         }
857         xd_maxsectors = 0x40;
858
859         outb(0,XD_RESET);               /* reset the controller */
860 }
861
862 static void __init xd_seagate_init_drive (u_char drive)
863 {
864         u_char cmdblk[6],buf[0x200];
865
866         xd_build(cmdblk,CMD_ST11GETGEOM,drive,0,0,0,1,0);
867         if (!xd_command(cmdblk,PIO_MODE,buf,0,0,XD_TIMEOUT * 2)) {
868                 xd_info[drive].heads = buf[0x04];                               /* heads */
869                 xd_info[drive].cylinders = (buf[0x02] << 8) | buf[0x03];        /* cylinders */
870                 xd_info[drive].sectors = buf[0x05];                             /* sectors */
871                 xd_info[drive].control = 0;                                     /* control byte */
872         }
873         else
874                 printk("xd_seagate_init_drive: error reading geometry from xd%c\n", 'a'+drive);
875 }
876
877 /* Omti support courtesy Dirk Melchers */
878 static void __init xd_omti_init_controller (unsigned int address)
879 {
880         switch (address) {
881                 case 0x00000:
882                 case 0xC8000:   break;                  /*initial: 0x320 */
883                 case 0xD0000:   xd_iobase = 0x324; break;
884                 case 0xD8000:   xd_iobase = 0x328; break;
885                 case 0xE0000:   xd_iobase = 0x32C; break;
886                 default:        printk("xd_omti_init_controller: unsupported BIOS address %06x\n",address);
887                                 break;
888         }
889         
890         xd_maxsectors = 0x40;
891
892         outb(0,XD_RESET);               /* reset the controller */
893 }
894
895 static void __init xd_omti_init_drive (u_char drive)
896 {
897         /* gets infos from drive */
898         xd_override_init_drive(drive);
899
900         /* set other parameters, Hardcoded, not that nice :-) */
901         xd_info[drive].control = 2;
902 }
903
904 /* Xebec support (AK) */
905 static void __init xd_xebec_init_controller (unsigned int address)
906 {
907 /* iobase may be set manually in range 0x300 - 0x33C
908       irq may be set manually to 2(9),3,4,5,6,7
909       dma may be set manually to 1,2,3
910         (How to detect them ???)
911 BIOS address may be set manually in range 0x0 - 0xF8000
912 If you need non-standard settings use the xd=... command */
913
914         switch (address) {
915                 case 0x00000:
916                 case 0xC8000:   /* initially: xd_iobase==0x320 */
917                 case 0xD0000:
918                 case 0xD2000:
919                 case 0xD4000:
920                 case 0xD6000:
921                 case 0xD8000:
922                 case 0xDA000:
923                 case 0xDC000:
924                 case 0xDE000:
925                 case 0xE0000:   break;
926                 default:        printk("xd_xebec_init_controller: unsupported BIOS address %06x\n",address);
927                                 break;
928                 }
929
930         xd_maxsectors = 0x01;
931         outb(0,XD_RESET);               /* reset the controller */
932
933         set_current_state(TASK_UNINTERRUPTIBLE);
934         schedule_timeout(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,0,0,0,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] < (sizeof(xd_sigs) / sizeof(xd_sigs[0]))))
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,0,&cmdblk[6],0,XD_TIMEOUT * 2))
1045                 printk("xd: error setting characteristics for xd%c\n", 'a'+drive);
1046 }
1047
1048
1049 #ifdef MODULE
1050
1051 MODULE_PARM(xd, "1-4i");
1052 MODULE_PARM(xd_geo, "3-6i");
1053 MODULE_PARM(nodma, "i");
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         devfs_remove("xd");
1068         if (xd_drives) {
1069                 free_irq(xd_irq, NULL);
1070                 free_dma(xd_dma);
1071                 if (xd_dma_buffer)
1072                         xd_dma_mem_free((unsigned long)xd_dma_buffer, xd_maxsectors * 0x200);
1073         }
1074 }
1075 #else
1076
1077 static int __init xd_setup (char *str)
1078 {
1079         int ints[5];
1080         get_options (str, ARRAY_SIZE (ints), ints);
1081         do_xd_setup (ints);
1082         return 1;
1083 }
1084
1085 /* xd_manual_geo_init: initialise drive geometry from command line parameters
1086    (used only for WD drives) */
1087 static int __init xd_manual_geo_init (char *str)
1088 {
1089         int i, integers[1 + 3*XD_MAXDRIVES];
1090
1091         get_options (str, ARRAY_SIZE (integers), integers);
1092         if (integers[0]%3 != 0) {
1093                 printk("xd: incorrect number of parameters for xd_geo\n");
1094                 return 1;
1095         }
1096         for (i = 0; (i < integers[0]) && (i < 3*XD_MAXDRIVES); i++)
1097                 xd_geo[i] = integers[i+1];
1098         return 1;
1099 }
1100
1101 __setup ("xd=", xd_setup);
1102 __setup ("xd_geo=", xd_manual_geo_init);
1103
1104 #endif /* MODULE */
1105
1106 module_init(xd_init)
1107