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