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