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