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
33 #include <linux/module.h>
34 #include <linux/errno.h>
35 #include <linux/sched.h>
36 #include <linux/mm.h>
37 #include <linux/fs.h>
38 #include <linux/kernel.h>
39 #include <linux/timer.h>
40 #include <linux/genhd.h>
41 #include <linux/hdreg.h>
42 #include <linux/ioport.h>
43 #include <linux/init.h>
44 #include <linux/devfs_fs_kernel.h>
45
46 #include <asm/system.h>
47 #include <asm/io.h>
48 #include <asm/uaccess.h>
49 #include <asm/dma.h>
50
51 #define MAJOR_NR XT_DISK_MAJOR
52 #include <linux/blk.h>
53 #include <linux/blkpg.h>
54
55 #include "xd.h"
56
57 #define XD_DONT_USE_DMA 0 /* Initial value. may be overriden using
58 "nodma" module option */
59 #define XD_INIT_DISK_DELAY (30*HZ/1000) /* 30 ms delay during disk initialization */
60
61 /* Above may need to be increased if a problem with the 2nd drive detection
62 (ST11M controller) or resetting a controler (WD) appears */
63
64 XD_INFO xd_info[XD_MAXDRIVES];
65
66 /* If you try this driver and find that your card is not detected by the driver at bootup, you need to add your BIOS
67 signature and details to the following list of signatures. A BIOS signature is a string embedded into the first
68 few bytes of your controller's on-board ROM BIOS. To find out what yours is, use something like MS-DOS's DEBUG
69 command. Run DEBUG, and then you can examine your BIOS signature with:
70
71 d xxxx:0000
72
73 where xxxx is the segment of your controller (like C800 or D000 or something). On the ASCII dump at the right, you should
74 be able to see a string mentioning the manufacturer's copyright etc. Add this string into the table below. The parameters
75 in the table are, in order:
76
77 offset ; this is the offset (in bytes) from the start of your ROM where the signature starts
78 signature ; this is the actual text of the signature
79 xd_?_init_controller ; this is the controller init routine used by your controller
80 xd_?_init_drive ; this is the drive init routine used by your controller
81
82 The controllers directly supported at the moment are: DTC 5150x, WD 1004A27X, ST11M/R and override. If your controller is
83 made by the same manufacturer as one of these, try using the same init routines as they do. If that doesn't work, your
84 best bet is to use the "override" routines. These routines use a "portable" method of getting the disk's geometry, and
85 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>.
86
87 NOTE: You can now specify your XT controller's parameters from the command line in the form xd=TYPE,IRQ,IO,DMA. The driver
88 should be able to detect your drive's geometry from this info. (eg: xd=0,5,0x320,3 is the "standard"). */
89
90 #include <asm/page.h>
91 #define xd_dma_mem_alloc(size) __get_dma_pages(GFP_KERNEL,get_order(size))
92 #define xd_dma_mem_free(addr, size) free_pages(addr, get_order(size))
93 static char *xd_dma_buffer = 0;
94
95 static XD_SIGNATURE xd_sigs[] __initdata = {
96 { 0x0000,"Override geometry handler",NULL,xd_override_init_drive,"n unknown" }, /* Pat Mackinlay, pat@it.com.au */
97 { 0x0008,"[BXD06 (C) DTC 17-MAY-1985]",xd_dtc_init_controller,xd_dtc5150cx_init_drive," DTC 5150CX" }, /* Andrzej Krzysztofowicz, ankry@mif.pg.gda.pl */
98 { 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 */
99 { 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 */
100 { 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 */
101 { 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 */
102 { 0x0015,"SEAGATE ST11 BIOS REVISION",xd_seagate_init_controller,xd_seagate_init_drive," Seagate ST11M/R" }, /* Salvador Abreu, spa@fct.unl.pt */
103 { 0x0010,"ST11R BIOS",xd_seagate_init_controller,xd_seagate_init_drive," Seagate ST11M/R" }, /* Risto Kankkunen, risto.kankkunen@cs.helsinki.fi */
104 { 0x0010,"ST11 BIOS v1.7",xd_seagate_init_controller,xd_seagate_init_drive," Seagate ST11R" }, /* Alan Hourihane, alanh@fairlite.demon.co.uk */
105 { 0x1000,"(c)Copyright 1987 SMS",xd_omti_init_controller,xd_omti_init_drive,"n OMTI 5520" }, /* Dirk Melchers, dirk@merlin.nbg.sub.org */
106 { 0x0006,"COPYRIGHT XEBEC (C) 1984",xd_xebec_init_controller,xd_xebec_init_drive," XEBEC" }, /* Andrzej Krzysztofowicz, ankry@mif.pg.gda.pl */
107 };
108
109 static unsigned int xd_bases[] __initdata =
110 {
111 0xC8000, 0xCA000, 0xCC000,
112 0xCE000, 0xD0000, 0xD2000,
113 0xD4000, 0xD6000, 0xD8000,
114 0xDA000, 0xDC000, 0xDE000,
115 0xE0000
116 };
117
118 static struct hd_struct xd_struct[XD_MAXDRIVES << 6];
119 static int xd_sizes[XD_MAXDRIVES << 6], xd_access[XD_MAXDRIVES];
120 static int xd_blocksizes[XD_MAXDRIVES << 6];
121
122 extern struct block_device_operations xd_fops;
123
124 static struct gendisk xd_gendisk = {
125 MAJOR_NR, /* Major number */
126 "xd", /* Major name */
127 6, /* Bits to shift to get real from partition */
128 1 << 6, /* Number of partitions per real */
129 xd_struct, /* hd struct */
130 xd_sizes, /* block sizes */
131 0, /* number */
132 (void *) xd_info, /* internal */
133 NULL, /* next */
134 &xd_fops, /* file operations */
135 };
136 static struct block_device_operations xd_fops = {
137 open: xd_open,
138 release: xd_release,
139 ioctl: xd_ioctl,
140 };
141 static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int);
142 static DECLARE_WAIT_QUEUE_HEAD(xd_wait_open);
143 static u_char xd_valid[XD_MAXDRIVES] = { 0,0 };
144 static u_char xd_drives, xd_irq = 5, xd_dma = 3, xd_maxsectors;
145 static u_char xd_override __initdata = 0, xd_type __initdata = 0;
146 static u_short xd_iobase = 0x320;
147 static int xd_geo[XD_MAXDRIVES*3] __initdata = { 0, };
148
149 static volatile int xdc_busy;
150 static DECLARE_WAIT_QUEUE_HEAD(xdc_wait);
151
152 static struct timer_list xd_timer, xd_watchdog_int;
153
154 static volatile u_char xd_error;
155 static int nodma = XD_DONT_USE_DMA;
156
157 static devfs_handle_t devfs_handle = NULL;
158
159 /* xd_init: register the block device number and set up pointer tables */
160 int __init xd_init (void)
161 {
162 init_timer (&xd_timer); xd_timer.function = xd_wakeup;
163 init_timer (&xd_watchdog_int); xd_watchdog_int.function = xd_watchdog;
164
165 if (devfs_register_blkdev(MAJOR_NR,"xd",&xd_fops)) {
166 printk("xd: Unable to get major number %d\n",MAJOR_NR);
167 return -1;
168 }
169 devfs_handle = devfs_mk_dir (NULL, xd_gendisk.major_name, NULL);
170 blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
171 read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB) read ahead */
172 xd_gendisk.next = gendisk_head;
173 gendisk_head = &xd_gendisk;
174 xd_geninit();
175
176 return 0;
177 }
178
179 /* xd_detect: scan the possible BIOS ROM locations for the signature strings */
180 static u_char __init xd_detect (u_char *controller, unsigned int *address)
181 {
182 u_char i,j,found = 0;
183
184 if (xd_override)
185 {
186 *controller = xd_type;
187 *address = 0;
188 return(1);
189 }
190
191 for (i = 0; i < (sizeof(xd_bases) / sizeof(xd_bases[0])) && !found; i++)
192 for (j = 1; j < (sizeof(xd_sigs) / sizeof(xd_sigs[0])) && !found; j++)
193 if (isa_check_signature(xd_bases[i] + xd_sigs[j].offset,xd_sigs[j].string,strlen(xd_sigs[j].string))) {
194 *controller = j;
195 xd_type = j;
196 *address = xd_bases[i];
197 found++;
198 }
199 return (found);
200 }
201
202 /* xd_geninit: grab the IRQ and DMA channel, initialise the drives */
203 /* and set up the "raw" device entries in the table */
204 static void __init xd_geninit (void)
205 {
206 u_char i,controller;
207 unsigned int address;
208
209 for(i=0;i<(XD_MAXDRIVES << 6);i++) xd_blocksizes[i] = 1024;
210 blksize_size[MAJOR_NR] = xd_blocksizes;
211
212 if (xd_detect(&controller,&address)) {
213
214 printk("Detected a%s controller (type %d) at address %06x\n",
215 xd_sigs[controller].name,controller,address);
216 if (check_region(xd_iobase,4)) {
217 printk("xd: Ports at 0x%x are not available\n",
218 xd_iobase);
219 return;
220 }
221 request_region(xd_iobase,4,"xd");
222 if (controller)
223 xd_sigs[controller].init_controller(address);
224 xd_drives = xd_initdrives(xd_sigs[controller].init_drive);
225
226 printk("Detected %d hard drive%s (using IRQ%d & DMA%d)\n",
227 xd_drives,xd_drives == 1 ? "" : "s",xd_irq,xd_dma);
228 for (i = 0; i < xd_drives; i++)
229 printk(" xd%c: CHS=%d/%d/%d\n",'a'+i,
230 xd_info[i].cylinders,xd_info[i].heads,
231 xd_info[i].sectors);
232
233 }
234 if (xd_drives) {
235 if (!request_irq(xd_irq,xd_interrupt_handler, 0, "XT hard disk", NULL)) {
236 if (request_dma(xd_dma,"xd")) {
237 printk("xd: unable to get DMA%d\n",xd_dma);
238 free_irq(xd_irq, NULL);
239 }
240 }
241 else
242 printk("xd: unable to get IRQ%d\n",xd_irq);
243 }
244
245 for (i = 0; i < xd_drives; i++) {
246 xd_valid[i] = 1;
247 register_disk(&xd_gendisk, MKDEV(MAJOR_NR,i<<6), 1<<6, &xd_fops,
248 xd_info[i].heads * xd_info[i].cylinders *
249 xd_info[i].sectors);
250 }
251
252 xd_gendisk.nr_real = xd_drives;
253
254 }
255
256 /* xd_open: open a device */
257 static int xd_open (struct inode *inode,struct file *file)
258 {
259 int dev = DEVICE_NR(inode->i_rdev);
260
261 MOD_INC_USE_COUNT;
262
263 if (dev < xd_drives) {
264 while (!xd_valid[dev])
265 sleep_on(&xd_wait_open);
266
267 xd_access[dev]++;
268
269 return (0);
270 }
271
272 MOD_DEC_USE_COUNT;
273 return -ENXIO;
274 }
275
276 /* do_xd_request: handle an incoming request */
277 static void do_xd_request (request_queue_t * q)
278 {
279 u_int block,count,retry;
280 int code;
281
282 sti();
283 if (xdc_busy)
284 return;
285 while (code = 0, !QUEUE_EMPTY) {
286 INIT_REQUEST; /* do some checking on the request structure */
287
288 if (CURRENT_DEV < xd_drives
289 && CURRENT->sector + CURRENT->nr_sectors
290 <= xd_struct[MINOR(CURRENT->rq_dev)].nr_sects) {
291 block = CURRENT->sector + xd_struct[MINOR(CURRENT->rq_dev)].start_sect;
292 count = CURRENT->nr_sectors;
293
294 switch (CURRENT->cmd) {
295 case READ:
296 case WRITE:
297 for (retry = 0; (retry < XD_RETRIES) && !code; retry++)
298 code = xd_readwrite(CURRENT->cmd,CURRENT_DEV,CURRENT->buffer,block,count);
299 break;
300 default:
301 printk("do_xd_request: unknown request\n");
302 break;
303 }
304 }
305 end_request(code); /* wrap up, 0 = fail, 1 = success */
306 }
307 }
308
309 /* xd_ioctl: handle device ioctl's */
310 static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg)
311 {
312 int dev;
313
314 if ((!inode) || !(inode->i_rdev))
315 return -EINVAL;
316 dev = DEVICE_NR(inode->i_rdev);
317
318 if (dev >= xd_drives) return -EINVAL;
319 switch (cmd) {
320 case HDIO_GETGEO:
321 {
322 struct hd_geometry g;
323 struct hd_geometry *geometry = (struct hd_geometry *) arg;
324 if (!geometry) return -EINVAL;
325 g.heads = xd_info[dev].heads;
326 g.sectors = xd_info[dev].sectors;
327 g.cylinders = xd_info[dev].cylinders;
328 g.start = xd_struct[MINOR(inode->i_rdev)].start_sect;
329 return copy_to_user(geometry, &g, sizeof g) ? -EFAULT : 0;
330 }
331 case BLKGETSIZE:
332 if (!arg) return -EINVAL;
333 return put_user(xd_struct[MINOR(inode->i_rdev)].nr_sects,(long *) arg);
334 case HDIO_SET_DMA:
335 if (!capable(CAP_SYS_ADMIN)) return -EACCES;
336 if (xdc_busy) return -EBUSY;
337 nodma = !arg;
338 if (nodma && xd_dma_buffer) {
339 xd_dma_mem_free((unsigned long)xd_dma_buffer, xd_maxsectors * 0x200);
340 xd_dma_buffer = 0;
341 }
342 return 0;
343 case HDIO_GET_DMA:
344 return put_user(!nodma, (long *) arg);
345 case HDIO_GET_MULTCOUNT:
346 return put_user(xd_maxsectors, (long *) arg);
347 case BLKRRPART:
348 if (!capable(CAP_SYS_ADMIN))
349 return -EACCES;
350 return xd_reread_partitions(inode->i_rdev);
351
352 case BLKFLSBUF:
353 case BLKROSET:
354 case BLKROGET:
355 case BLKRASET:
356 case BLKRAGET:
357 case BLKPG:
358 return blk_ioctl(inode->i_rdev, cmd, arg);
359
360 default:
361 return -EINVAL;
362 }
363 }
364
365 /* xd_release: release the device */
366 static int xd_release (struct inode *inode, struct file *file)
367 {
368 int target = DEVICE_NR(inode->i_rdev);
369 if (target < xd_drives) {
370 xd_access[target]--;
371 #ifdef MODULE
372 MOD_DEC_USE_COUNT;
373 #endif /* MODULE */
374 }
375 return 0;
376 }
377
378 /* xd_reread_partitions: rereads the partition table from a drive */
379 static int xd_reread_partitions(kdev_t dev)
380 {
381 int target;
382 int start;
383 int partition;
384
385 target = DEVICE_NR(dev);
386 start = target << xd_gendisk.minor_shift;
387
388 cli();
389 xd_valid[target] = (xd_access[target] != 1);
390 sti();
391 if (xd_valid[target])
392 return -EBUSY;
393
394 for (partition = xd_gendisk.max_p - 1; partition >= 0; partition--) {
395 int minor = (start | partition);
396 kdev_t devp = MKDEV(MAJOR_NR, minor);
397 struct super_block * sb = get_super(devp);
398
399 sync_dev(devp);
400 if (sb)
401 invalidate_inodes(sb);
402 invalidate_buffers(devp);
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 controler 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 controler 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 static void xd_done (void)
1112 {
1113 struct gendisk ** gdp;
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 for (gdp = &gendisk_head; *gdp; gdp = &((*gdp)->next))
1121 if (*gdp == &xd_gendisk)
1122 break;
1123 if (*gdp)
1124 *gdp = (*gdp)->next;
1125 release_region(xd_iobase,4);
1126 }
1127
1128 int init_module(void)
1129 {
1130 int i,count = 0;
1131 int error;
1132
1133 for (i = 4; i > 0; i--)
1134 if(((xd[i] = xd[i-1]) >= 0) && !count)
1135 count = i;
1136 if((xd[0] = count))
1137 do_xd_setup(xd);
1138
1139 error = xd_init();
1140 if (error) return error;
1141
1142 printk(KERN_INFO "XD: Loaded as a module.\n");
1143 if (!xd_drives) {
1144 /* no drives detected - unload module */
1145 devfs_unregister_blkdev(MAJOR_NR, "xd");
1146 xd_done();
1147 return (-1);
1148 }
1149
1150 return 0;
1151 }
1152
1153 void cleanup_module(void)
1154 {
1155 int partition,dev,start;
1156
1157 devfs_unregister_blkdev(MAJOR_NR, "xd");
1158 for (dev = 0; dev < xd_drives; dev++) {
1159 start = dev << xd_gendisk.minor_shift;
1160 for (partition = xd_gendisk.max_p - 1; partition >= 0; partition--) {
1161 int minor = (start | partition);
1162 kdev_t devp = MKDEV(MAJOR_NR, minor);
1163 start = dev << xd_gendisk.minor_shift;
1164 sync_dev(devp);
1165 invalidate_buffers(devp);
1166 }
1167 }
1168 xd_done();
1169 devfs_unregister (devfs_handle);
1170 if (xd_drives) {
1171 free_irq(xd_irq, NULL);
1172 free_dma(xd_dma);
1173 if (xd_dma_buffer)
1174 xd_dma_mem_free((unsigned long)xd_dma_buffer, xd_maxsectors * 0x200);
1175 }
1176 }
1177 #else
1178
1179 static int __init xd_setup (char *str)
1180 {
1181 int ints[5];
1182 get_options (str, ARRAY_SIZE (ints), ints);
1183 do_xd_setup (ints);
1184 return 1;
1185 }
1186
1187 /* xd_manual_geo_init: initialise drive geometry from command line parameters
1188 (used only for WD drives) */
1189 static int __init xd_manual_geo_init (char *str)
1190 {
1191 int i, integers[1 + 3*XD_MAXDRIVES];
1192
1193 get_options (str, ARRAY_SIZE (integers), integers);
1194 if (integers[0]%3 != 0) {
1195 printk("xd: incorrect number of parameters for xd_geo\n");
1196 return 1;
1197 }
1198 for (i = 0; (i < integers[0]) && (i < 3*XD_MAXDRIVES); i++)
1199 xd_geo[i] = integers[i+1];
1200 return 1;
1201 }
1202
1203 __setup ("xd=", xd_setup);
1204 __setup ("xd_geo=", xd_manual_geo_init);
1205
1206 #endif /* MODULE */
1207
1208
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.