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