2 * This file contains the driver for an XT hard disk controller
3 * (at least the DTC 5150X) for Linux.
5 * Author: Pat Mackinlay, pat@it.com.au
8 * Revised: 01/01/93, ...
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
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,
21 * Modularized: 04/10/96 by Todd Fries, tfries@umr.edu
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)
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.
32 * Bugfix: 15/02/01, Paul G. - inform queue layer of tiny xd_maxsect.
36 #include <linux/module.h>
37 #include <linux/errno.h>
38 #include <linux/sched.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>
49 #include <asm/system.h>
51 #include <asm/uaccess.h>
54 #define MAJOR_NR XT_DISK_MAJOR
55 #include <linux/blk.h>
56 #include <linux/blkpg.h>
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 */
64 /* Above may need to be increased if a problem with the 2nd drive detection
65 (ST11M controller) or resetting a controller (WD) appears */
67 XD_INFO xd_info[XD_MAXDRIVES];
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:
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:
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
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>.
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"). */
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;
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 */
114 static unsigned int xd_bases[] __initdata =
116 0xC8000, 0xCA000, 0xCC000,
117 0xCE000, 0xD0000, 0xD2000,
118 0xD4000, 0xD6000, 0xD8000,
119 0xDA000, 0xDC000, 0xDE000,
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];
128 extern struct block_device_operations xd_fops;
130 static struct gendisk xd_gendisk = {
137 real_devices: (void *)xd_info,
141 static struct block_device_operations xd_fops = {
148 static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int);
149 static DECLARE_WAIT_QUEUE_HEAD(xd_wait_open);
150 static u8 xd_valid[XD_MAXDRIVES] = { 0,0 };
151 static u8 xd_drives, xd_irq = 5, xd_dma = 3, xd_maxsectors;
152 static u8 xd_override __initdata = 0, xd_type __initdata = 0;
153 static u16 xd_iobase = 0x320;
154 static int xd_geo[XD_MAXDRIVES*3] __initdata = { 0, };
156 static volatile int xdc_busy;
158 static struct timer_list xd_watchdog_int;
160 static volatile u8 xd_error;
161 static int nodma = XD_DONT_USE_DMA;
163 static devfs_handle_t devfs_handle = NULL;
165 /* xd_init: register the block device number and set up pointer tables */
166 int __init xd_init(void)
168 init_timer (&xd_watchdog_int);
169 xd_watchdog_int.function = xd_watchdog;
172 xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
175 printk(KERN_ERR "xd: Out of memory.\n");
179 if (devfs_register_blkdev(MAJOR_NR,"xd",&xd_fops)) {
180 printk(KERN_ERR "xd: Unable to get major number %d\n",MAJOR_NR);
183 devfs_handle = devfs_mk_dir (NULL, xd_gendisk.major_name, NULL);
184 blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
185 read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB) read ahead */
186 add_gendisk(&xd_gendisk);
192 /* xd_detect: scan the possible BIOS ROM locations for the signature strings */
194 static u8 __init xd_detect (u8 *controller, unsigned int *address)
200 *controller = xd_type;
205 for (i = 0; i < (sizeof(xd_bases) / sizeof(xd_bases[0])) && !found; i++)
206 for (j = 1; j < (sizeof(xd_sigs) / sizeof(xd_sigs[0])) && !found; j++)
207 if (isa_check_signature(xd_bases[i] + xd_sigs[j].offset,xd_sigs[j].string,strlen(xd_sigs[j].string))) {
210 *address = xd_bases[i];
216 /* xd_geninit: grab the IRQ and DMA channel, initialise the drives */
217 /* and set up the "raw" device entries in the table */
219 static void __init xd_geninit (void)
222 unsigned int address;
224 for(i=0;i<(XD_MAXDRIVES << 6);i++)
225 xd_blocksizes[i] = 1024;
227 blksize_size[MAJOR_NR] = xd_blocksizes;
229 if (xd_detect(&controller,&address)) {
230 printk(KERN_INFO "Detected a%s controller (type %d) at address %06x\n",
231 xd_sigs[controller].name,controller,address);
232 if (!request_region(xd_iobase,4, "xd")) {
233 printk(KERN_ERR "xd: Ports at 0x%x are not available\n", xd_iobase);
237 xd_sigs[controller].init_controller(address);
238 xd_drives = xd_initdrives(xd_sigs[controller].init_drive);
240 printk(KERN_INFO "Detected %d hard drive%s (using IRQ%d & DMA%d)\n",
241 xd_drives,xd_drives == 1 ? "" : "s",xd_irq,xd_dma);
242 for (i = 0; i < xd_drives; i++)
243 printk(KERN_INFO " xd%c: CHS=%d/%d/%d\n",'a'+i,
244 xd_info[i].cylinders,xd_info[i].heads,
249 if (!request_irq(xd_irq,xd_interrupt_handler, 0, "XT hard disk", NULL)) {
250 if (request_dma(xd_dma,"xd")) {
251 printk(KERN_ERR "xd: unable to get DMA%d\n",xd_dma);
252 free_irq(xd_irq, NULL);
256 printk(KERN_ERR "xd: unable to get IRQ%d\n",xd_irq);
259 /* xd_maxsectors depends on controller - so set after detection */
260 for(i=0; i<(XD_MAXDRIVES << 6); i++) xd_maxsect[i] = xd_maxsectors;
261 max_sectors[MAJOR_NR] = xd_maxsect;
263 for (i = 0; i < xd_drives; i++) {
265 register_disk(&xd_gendisk, MKDEV(MAJOR_NR,i<<6), 1<<6, &xd_fops,
266 xd_info[i].heads * xd_info[i].cylinders *
270 xd_gendisk.nr_real = xd_drives;
274 /* xd_open: open a device */
275 static int xd_open (struct inode *inode,struct file *file)
277 int dev = DEVICE_NR(inode->i_rdev);
279 if (dev < xd_drives) {
280 while (!xd_valid[dev])
281 sleep_on(&xd_wait_open);
289 /* do_xd_request: handle an incoming request */
290 static void do_xd_request (request_queue_t * q)
292 unsigned int block,count,retry;
298 while (code = 0, !QUEUE_EMPTY) {
299 INIT_REQUEST; /* do some checking on the request structure */
301 if (CURRENT_DEV < xd_drives && CURRENT->sector + CURRENT->nr_sectors <= xd_struct[MINOR(CURRENT->rq_dev)].nr_sects) {
302 block = CURRENT->sector + xd_struct[MINOR(CURRENT->rq_dev)].start_sect;
303 count = CURRENT->nr_sectors;
305 switch (CURRENT->cmd) {
308 for (retry = 0; (retry < XD_RETRIES) && !code; retry++)
309 code = xd_readwrite(CURRENT->cmd,CURRENT_DEV,CURRENT->buffer,block,count);
315 end_request(code); /* wrap up, 0 = fail, 1 = success */
319 /* xd_ioctl: handle device ioctl's */
321 static int xd_ioctl (struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg)
325 if ((!inode) || !(inode->i_rdev))
327 dev = DEVICE_NR(inode->i_rdev);
329 if (dev >= xd_drives) return -EINVAL;
333 struct hd_geometry g;
334 struct hd_geometry *geometry = (struct hd_geometry *) arg;
335 g.heads = xd_info[dev].heads;
336 g.sectors = xd_info[dev].sectors;
337 g.cylinders = xd_info[dev].cylinders;
338 g.start = xd_struct[MINOR(inode->i_rdev)].start_sect;
339 return copy_to_user(geometry, &g, sizeof g) ? -EFAULT : 0;
342 if (!capable(CAP_SYS_ADMIN))
349 if (nodma && xd_dma_buffer) {
350 xd_dma_mem_free((unsigned long)xd_dma_buffer, xd_maxsectors * 0x200);
352 } else if (!nodma && !xd_dma_buffer) {
353 xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
356 nodma = XD_DONT_USE_DMA;
362 return put_user(!nodma, (long *) arg);
363 case HDIO_GET_MULTCOUNT:
364 return put_user(xd_maxsectors, (long *) arg);
366 if (!capable(CAP_SYS_ADMIN))
368 return xd_reread_partitions(inode->i_rdev);
377 return blk_ioctl(inode->i_rdev, cmd, arg);
383 /* xd_release: release the device */
384 static int xd_release (struct inode *inode, struct file *file)
386 int target = DEVICE_NR(inode->i_rdev);
387 if (target < xd_drives)
392 /* xd_reread_partitions: rereads the partition table from a drive */
393 static int xd_reread_partitions(kdev_t dev)
399 target = DEVICE_NR(dev);
400 start = target << xd_gendisk.minor_shift;
403 xd_valid[target] = (xd_access[target] != 1);
405 if (xd_valid[target])
408 for (partition = xd_gendisk.max_p - 1; partition >= 0; partition--) {
409 int minor = (start | partition);
410 invalidate_device(MKDEV(MAJOR_NR, minor), 1);
411 xd_gendisk.part[minor].start_sect = 0;
412 xd_gendisk.part[minor].nr_sects = 0;
415 grok_partitions(&xd_gendisk, target, 1<<6,
416 xd_info[target].heads * xd_info[target].cylinders * xd_info[target].sectors);
418 xd_valid[target] = 1;
419 wake_up(&xd_wait_open);
424 /* xd_readwrite: handle a read/write request */
425 static int xd_readwrite (u8 operation,u8 drive,char *buffer,unsigned int block,unsigned int count)
427 u8 cmdblk[6],sense[4];
429 u8 head,sector,control,mode = PIO_MODE,temp;
432 #ifdef DEBUG_READWRITE
433 printk(KERN_DEBUG "xd_readwrite: operation = %s, drive = %d, buffer = 0x%X, block = %d, count = %d\n",operation == READ ? "read" : "write",drive,buffer,block,count);
434 #endif /* DEBUG_READWRITE */
436 spin_unlock_irq(&io_request_lock);
438 control = xd_info[drive].control;
440 temp = count < xd_maxsectors ? count : xd_maxsectors;
442 track = block / xd_info[drive].sectors;
443 head = track % xd_info[drive].heads;
444 cylinder = track / xd_info[drive].heads;
445 sector = block % xd_info[drive].sectors;
447 #ifdef DEBUG_READWRITE
448 printk(KERN_DEBUG "xd_readwrite: drive = %d, head = %d, cylinder = %d, sector = %d, count = %d\n",drive,head,cylinder,sector,temp);
449 #endif /* DEBUG_READWRITE */
452 mode = xd_setup_dma(operation == READ ? DMA_MODE_READ : DMA_MODE_WRITE,(u8 *)(xd_dma_buffer),temp * 0x200);
453 real_buffer = &xd_dma_buffer;
454 memcpy(xd_dma_buffer, buffer, temp * 0x200);
457 real_buffer = &buffer;
459 xd_build(cmdblk,operation == READ ? CMD_READ : CMD_WRITE,drive,head,cylinder,sector,temp & 0xFF,control);
461 switch (xd_command(cmdblk,mode,(u8 *)(*real_buffer),(u8 *)(*real_buffer),sense,XD_TIMEOUT))
464 printk(KERN_WARNING "xd%c: %s timeout, recalibrating drive\n",'a'+drive,(operation == READ ? "read" : "write"));
465 xd_recalibrate(drive);
468 if (sense[0] & 0x30) {
469 printk(KERN_ERR "xd%c: %s - ",'a'+drive,(operation == READ ? "reading" : "writing"));
470 switch ((sense[0] & 0x30) >> 4) {
471 case 0: printk("drive error, code = 0x%X",sense[0] & 0x0F);
473 case 1: printk("controller error, code = 0x%X",sense[0] & 0x0F);
475 case 2: printk("command error, code = 0x%X",sense[0] & 0x0F);
477 case 3: printk("miscellaneous error, code = 0x%X",sense[0] & 0x0F);
482 printk(" - CHS = %d/%d/%d\n",((sense[2] & 0xC0) << 2) | sense[3],sense[1] & 0x1F,sense[2] & 0x3F);
483 /* reported drive number = (sense[1] & 0xE0) >> 5 */
485 printk(" - no valid disk address\n");
489 memcpy(buffer, xd_dma_buffer, (temp * 0x200));
491 count -= temp, buffer += temp * 0x200, block += temp;
493 spin_lock_irq(&io_request_lock);
497 spin_lock_irq(&io_request_lock);
502 /* xd_recalibrate: recalibrate a given drive and reset controller if necessary */
503 static void xd_recalibrate (u8 drive)
507 xd_build(cmdblk,CMD_RECALIBRATE,drive,0,0,0,0,0);
508 if (xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 8))
509 printk(KERN_WARNING "xd%c: warning! error recalibrating, controller may be unstable\n", 'a'+drive);
512 /* xd_interrupt_handler: interrupt service routine */
513 static void xd_interrupt_handler(int irq, void *dev_id, struct pt_regs * regs)
515 if (inb(XD_STATUS) & STAT_INTERRUPT) { /* check if it was our device */
517 printk(KERN_DEBUG "xd_interrupt_handler: interrupt detected\n");
518 #endif /* DEBUG_OTHER */
519 outb(0,XD_CONTROL); /* acknowledge interrupt */
520 wake_up(&xd_wait_int); /* and wake up sleeping processes */
523 printk(KERN_DEBUG "xd: unexpected interrupt\n");
526 /* xd_setup_dma: set up the DMA controller for a data transfer */
527 static u8 xd_setup_dma (u8 mode,u8 *buffer,unsigned int count)
533 if (((unsigned long) buffer & 0xFFFF0000) != (((unsigned long) buffer + count) & 0xFFFF0000)) {
535 printk(KERN_DEBUG "xd_setup_dma: using PIO, transfer overlaps 64k boundary\n");
536 #endif /* DEBUG_OTHER */
542 clear_dma_ff(xd_dma);
543 set_dma_mode(xd_dma,mode);
544 set_dma_addr(xd_dma, (unsigned long) buffer);
545 set_dma_count(xd_dma,count);
549 return DMA_MODE; /* use DMA and INT */
552 /* xd_build: put stuff into an array in a format suitable for the controller */
553 static u8 *xd_build (u8 *cmdblk,u8 command,u8 drive,u8 head,u16 cylinder,u8 sector,u8 count,u8 control)
556 cmdblk[1] = ((drive & 0x07) << 5) | (head & 0x1F);
557 cmdblk[2] = ((cylinder & 0x300) >> 2) | (sector & 0x3F);
558 cmdblk[3] = cylinder & 0xFF;
565 /* xd_wakeup is called from timer interrupt */
566 static void xd_watchdog (unsigned long unused)
569 wake_up(&xd_wait_int);
572 /* xd_waitport: waits until port & mask == flags or a timeout occurs. return 1 for a timeout */
573 static inline u8 xd_waitport (u16 port,u8 flags,u8 mask,unsigned long timeout)
575 unsigned long expiry = jiffies + timeout;
579 while ((success = ((inb(port) & mask) != flags)) && time_before(jiffies, expiry)) {
580 set_current_state(TASK_UNINTERRUPTIBLE);
587 static inline unsigned int xd_wait_for_IRQ (void)
590 xd_watchdog_int.expires = jiffies + 8 * HZ;
591 add_timer(&xd_watchdog_int);
593 flags=claim_dma_lock();
595 release_dma_lock(flags);
597 sleep_on(&xd_wait_int);
598 del_timer_sync(&xd_watchdog_int);
601 flags=claim_dma_lock();
603 release_dma_lock(flags);
606 printk(KERN_DEBUG "xd: missed IRQ - command aborted\n");
613 /* xd_command: handle all data transfers necessary for a single command */
614 static unsigned int xd_command (u8 *command,u8 mode,u8 *indata,u8 *outdata,u8 *sense,unsigned long timeout)
620 printk(KERN_DEBUG "xd_command: command = 0x%X, mode = 0x%X, indata = 0x%X, outdata = 0x%X, sense = 0x%X\n",command,mode,indata,outdata,sense);
621 #endif /* DEBUG_COMMAND */
624 outb(mode,XD_CONTROL);
626 if (xd_waitport(XD_STATUS,STAT_SELECT,STAT_SELECT,timeout))
630 if (xd_waitport(XD_STATUS,STAT_READY,STAT_READY,timeout))
633 switch (inb(XD_STATUS) & (STAT_COMMAND | STAT_INPUT)) {
635 if (mode == DMA_MODE) {
636 if (xd_wait_for_IRQ())
639 outb(outdata ? *outdata++ : 0,XD_DATA);
642 if (mode == DMA_MODE) {
643 if (xd_wait_for_IRQ())
647 *indata++ = inb(XD_DATA);
652 outb(command ? *command++ : 0,XD_DATA);
654 case STAT_COMMAND | STAT_INPUT:
661 if (xd_waitport(XD_STATUS,0,STAT_SELECT,timeout)) /* wait until deselected */
664 if (csb & CSB_ERROR) { /* read sense data if error */
665 xd_build(cmdblk,CMD_SENSE,(csb & CSB_LUN) >> 5,0,0,0,0,0);
666 if (xd_command(cmdblk,0,sense,0,0,XD_TIMEOUT))
667 printk(KERN_DEBUG "xd: warning! sense command failed!\n");
671 printk(KERN_DEBUG "xd_command: completed with csb = 0x%X\n",csb);
672 #endif /* DEBUG_COMMAND */
674 return (csb & CSB_ERROR);
677 static u8 __init xd_initdrives (void (*init_drive)(u8 drive))
679 u8 cmdblk[6],i,count = 0;
681 for (i = 0; i < XD_MAXDRIVES; i++) {
682 xd_build(cmdblk,CMD_TESTREADY,i,0,0,0,0,0);
683 if (!xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 8)) {
684 set_current_state(TASK_INTERRUPTIBLE);
685 schedule_timeout(XD_INIT_DISK_DELAY);
690 set_current_state(TASK_INTERRUPTIBLE);
691 schedule_timeout(XD_INIT_DISK_DELAY);
697 static void __init xd_manual_geo_set (u8 drive)
699 xd_info[drive].heads = xd_geo[3 * drive + 1];
700 xd_info[drive].cylinders= xd_geo[3 * drive];
701 xd_info[drive].sectors = xd_geo[3 * drive + 2];
704 static void __init xd_dtc_init_controller (unsigned int address)
709 break; /*initial: 0x320 */
712 case 0xD0000: /*5150CX*/
714 break; /*5150CX & 5150XL*/
716 printk(KERN_ERR "xd_dtc_init_controller: unsupported BIOS address %06x\n",address);
719 xd_maxsectors = 0x01; /* my card seems to have trouble doing multi-block transfers? */
721 outb(0,XD_RESET); /* reset the controller */
725 static void __init xd_dtc5150cx_init_drive (u8 drive)
727 /* values from controller's BIOS - BIOS chip may be removed */
728 static u16 geometry_table[][4] = {
729 {0x200,8,0x200,0x100},
730 {0x267,2,0x267,0x267},
731 {0x264,4,0x264,0x80},
733 {0x132,2,0x80, 0x132},
737 {0x132,6,0x80, 0x100},
738 {0x200,6,0x100,0x100},
739 {0x264,2,0x264,0x80},
740 {0x280,4,0x280,0x100},
741 {0x2B9,3,0x2B9,0x2B9},
742 {0x2B9,5,0x2B9,0x2B9},
743 {0x280,6,0x280,0x100},
744 {0x132,4,0x132,0x0}};
748 n = (drive ? n : (n >> 2)) & 0x33;
749 n = (n | (n >> 2)) & 0x0F;
751 xd_manual_geo_set(drive);
754 xd_info[drive].heads = (u8)(geometry_table[n][1]); /* heads */
755 xd_info[drive].cylinders = geometry_table[n][0]; /* cylinders */
756 xd_info[drive].sectors = 17; /* sectors */
758 xd_info[drive].rwrite = geometry_table[n][2]; /* reduced write */
759 xd_info[drive].precomp = geometry_table[n][3] /* write precomp */
760 xd_info[drive].ecc = 0x0B; /* ecc length */
764 printk(KERN_WARNING "xd%c: undetermined drive geometry\n",'a'+drive);
767 xd_info[drive].control = 5; /* control byte */
768 xd_setparam(CMD_DTCSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,geometry_table[n][2],geometry_table[n][3],0x0B);
769 xd_recalibrate(drive);
772 static void __init xd_dtc_init_drive (u8 drive)
774 u8 cmdblk[6],buf[64];
776 xd_build(cmdblk,CMD_DTCGETGEOM,drive,0,0,0,0,0);
777 if (!xd_command(cmdblk,PIO_MODE,buf,0,0,XD_TIMEOUT * 2)) {
778 xd_info[drive].heads = buf[0x0A]; /* heads */
779 xd_info[drive].cylinders = ((u16 *) (buf))[0x04]; /* cylinders */
780 xd_info[drive].sectors = 17; /* sectors */
782 xd_manual_geo_set(drive);
784 xd_info[drive].rwrite = ((u16 *) (buf + 1))[0x05]; /* reduced write */
785 xd_info[drive].precomp = ((u16 *) (buf + 1))[0x06]; /* write precomp */
786 xd_info[drive].ecc = buf[0x0F]; /* ecc length */
788 xd_info[drive].control = 0; /* control byte */
790 xd_setparam(CMD_DTCSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,((u16 *) (buf + 1))[0x05],((u16 *) (buf + 1))[0x06],buf[0x0F]);
791 xd_build(cmdblk,CMD_DTCSETSTEP,drive,0,0,0,0,7);
792 if (xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 2))
793 printk(KERN_WARNING "xd_dtc_init_drive: error setting step rate for xd%c\n", 'a'+drive);
796 printk(KERN_WARNING "xd_dtc_init_drive: error reading geometry for xd%c\n", 'a'+drive);
799 static void __init xd_wd_init_controller (unsigned int address)
803 case 0xC8000: break; /*initial: 0x320 */
804 case 0xCA000: xd_iobase = 0x324; break;
805 case 0xCC000: xd_iobase = 0x328; break;
806 case 0xCE000: xd_iobase = 0x32C; break;
807 case 0xD0000: xd_iobase = 0x328; break; /* ? */
808 case 0xD8000: xd_iobase = 0x32C; break; /* ? */
809 default: printk(KERN_ERR "xd_wd_init_controller: unsupported BIOS address %06x\n",address);
812 xd_maxsectors = 0x01; /* this one doesn't wrap properly either... */
814 outb(0,XD_RESET); /* reset the controller */
816 set_current_state(TASK_UNINTERRUPTIBLE);
817 schedule_timeout(XD_INIT_DISK_DELAY);
820 static void __init xd_wd_init_drive (u8 drive)
822 /* values from controller's BIOS - BIOS may be disabled */
823 static u16 geometry_table[][4] = {
824 {0x264,4,0x1C2,0x1C2}, /* common part */
826 {0x267,2,0x1C2,0x1C2},
827 {0x267,4,0x1C2,0x1C2},
829 {0x334,6,0x335,0x335}, /* 1004 series RLL */
830 {0x30E,4,0x30F,0x3DC},
831 {0x30E,2,0x30F,0x30F},
832 {0x267,4,0x268,0x268},
834 {0x3D5,5,0x3D6,0x3D6}, /* 1002 series RLL */
835 {0x3DB,7,0x3DC,0x3DC},
836 {0x264,4,0x265,0x265},
837 {0x267,4,0x268,0x268}};
839 u8 cmdblk[6],buf[0x200];
840 u8 n = 0,rll,jumper_state,use_jumper_geo;
841 u8 wd_1002 = (xd_sigs[xd_type].string[7] == '6');
843 jumper_state = ~(inb(0x322));
844 if (jumper_state & 0x40)
846 rll = (jumper_state & 0x30) ? (0x04 << wd_1002) : 0;
847 xd_build(cmdblk,CMD_READ,drive,0,0,0,1,0);
848 if (!xd_command(cmdblk,PIO_MODE,buf,0,0,XD_TIMEOUT * 2)) {
849 xd_info[drive].heads = buf[0x1AF]; /* heads */
850 xd_info[drive].cylinders = ((u16 *) (buf + 1))[0xD6]; /* cylinders */
851 xd_info[drive].sectors = 17; /* sectors */
853 xd_manual_geo_set(drive);
855 xd_info[drive].rwrite = ((u16 *) (buf))[0xD8]; /* reduced write */
856 xd_info[drive].wprecomp = ((u16 *) (buf))[0xDA]; /* write precomp */
857 xd_info[drive].ecc = buf[0x1B4]; /* ecc length */
859 xd_info[drive].control = buf[0x1B5]; /* control byte */
860 use_jumper_geo = !(xd_info[drive].heads) || !(xd_info[drive].cylinders);
861 if (xd_geo[3*drive]) {
862 xd_manual_geo_set(drive);
863 xd_info[drive].control = rll ? 7 : 5;
865 else if (use_jumper_geo) {
866 n = (((jumper_state & 0x0F) >> (drive << 1)) & 0x03) | rll;
867 xd_info[drive].cylinders = geometry_table[n][0];
868 xd_info[drive].heads = (u8)(geometry_table[n][1]);
869 xd_info[drive].control = rll ? 7 : 5;
871 xd_info[drive].rwrite = geometry_table[n][2];
872 xd_info[drive].wprecomp = geometry_table[n][3];
873 xd_info[drive].ecc = 0x0B;
878 xd_setparam(CMD_WDSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,
879 geometry_table[n][2],geometry_table[n][3],0x0B);
881 xd_setparam(CMD_WDSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,
882 ((u16 *) (buf))[0xD8],((u16 *) (buf))[0xDA],buf[0x1B4]);
884 /* 1002 based RLL controller requests converted addressing, but reports physical
885 (physical 26 sec., logical 17 sec.)
888 if ((xd_info[drive].cylinders *= 26,
889 xd_info[drive].cylinders /= 17) > 1023)
890 xd_info[drive].cylinders = 1023; /* 1024 ? */
892 xd_info[drive].rwrite *= 26;
893 xd_info[drive].rwrite /= 17;
894 xd_info[drive].wprecomp *= 26
895 xd_info[drive].wprecomp /= 17;
900 printk(KERN_WARNING "xd_wd_init_drive: error reading geometry for xd%c\n",'a'+drive);
904 static void __init xd_seagate_init_controller (unsigned int address)
908 case 0xC8000: break; /*initial: 0x320 */
909 case 0xD0000: xd_iobase = 0x324; break;
910 case 0xD8000: xd_iobase = 0x328; break;
911 case 0xE0000: xd_iobase = 0x32C; break;
912 default: printk(KERN_ERR "xd_seagate_init_controller: unsupported BIOS address %06x\n",address);
915 xd_maxsectors = 0x40;
917 outb(0,XD_RESET); /* reset the controller */
920 static void __init xd_seagate_init_drive (u8 drive)
922 u8 cmdblk[6],buf[0x200];
924 xd_build(cmdblk,CMD_ST11GETGEOM,drive,0,0,0,1,0);
925 if (!xd_command(cmdblk,PIO_MODE,buf,0,0,XD_TIMEOUT * 2)) {
926 xd_info[drive].heads = buf[0x04]; /* heads */
927 xd_info[drive].cylinders = (buf[0x02] << 8) | buf[0x03]; /* cylinders */
928 xd_info[drive].sectors = buf[0x05]; /* sectors */
929 xd_info[drive].control = 0; /* control byte */
932 printk(KERN_WARNING "xd_seagate_init_drive: error reading geometry from xd%c\n", 'a'+drive);
935 /* Omti support courtesy Dirk Melchers */
936 static void __init xd_omti_init_controller (unsigned int address)
940 case 0xC8000: break; /*initial: 0x320 */
941 case 0xD0000: xd_iobase = 0x324; break;
942 case 0xD8000: xd_iobase = 0x328; break;
943 case 0xE0000: xd_iobase = 0x32C; break;
944 default: printk(KERN_ERR "xd_omti_init_controller: unsupported BIOS address %06x\n",address);
948 xd_maxsectors = 0x40;
950 outb(0,XD_RESET); /* reset the controller */
953 static void __init xd_omti_init_drive (u8 drive)
955 /* gets infos from drive */
956 xd_override_init_drive(drive);
958 /* set other parameters, Hardcoded, not that nice :-) */
959 xd_info[drive].control = 2;
962 /* Xebec support (AK) */
963 static void __init xd_xebec_init_controller (unsigned int address)
965 /* iobase may be set manually in range 0x300 - 0x33C
966 irq may be set manually to 2(9),3,4,5,6,7
967 dma may be set manually to 1,2,3
968 (How to detect them ???)
969 BIOS address may be set manually in range 0x0 - 0xF8000
970 If you need non-standard settings use the xd=... command */
974 case 0xC8000: /* initially: xd_iobase==0x320 */
984 default: printk(KERN_ERR "xd_xebec_init_controller: unsupported BIOS address %06x\n",address);
988 xd_maxsectors = 0x01;
989 outb(0,XD_RESET); /* reset the controller */
991 set_current_state(TASK_UNINTERRUPTIBLE);
992 schedule_timeout(XD_INIT_DISK_DELAY);
995 static void __init xd_xebec_init_drive (u8 drive)
997 /* values from controller's BIOS - BIOS chip may be removed */
998 static u16 geometry_table[][5] = {
999 {0x132,4,0x080,0x080,0x7},
1000 {0x132,4,0x080,0x080,0x17},
1001 {0x264,2,0x100,0x100,0x7},
1002 {0x264,2,0x100,0x100,0x17},
1003 {0x132,8,0x080,0x080,0x7},
1004 {0x132,8,0x080,0x080,0x17},
1005 {0x264,4,0x100,0x100,0x6},
1006 {0x264,4,0x100,0x100,0x17},
1007 {0x2BC,5,0x2BC,0x12C,0x6},
1008 {0x3A5,4,0x3A5,0x3A5,0x7},
1009 {0x26C,6,0x26C,0x26C,0x7},
1010 {0x200,8,0x200,0x100,0x17},
1011 {0x400,5,0x400,0x400,0x7},
1012 {0x400,6,0x400,0x400,0x7},
1013 {0x264,8,0x264,0x200,0x17},
1014 {0x33E,7,0x33E,0x200,0x7}};
1017 n = inb(XD_JUMPER) & 0x0F; /* BIOS's drive number: same geometry
1018 is assumed for BOTH drives */
1019 if (xd_geo[3*drive])
1020 xd_manual_geo_set(drive);
1022 xd_info[drive].heads = (u8)(geometry_table[n][1]); /* heads */
1023 xd_info[drive].cylinders = geometry_table[n][0]; /* cylinders */
1024 xd_info[drive].sectors = 17; /* sectors */
1026 xd_info[drive].rwrite = geometry_table[n][2]; /* reduced write */
1027 xd_info[drive].precomp = geometry_table[n][3] /* write precomp */
1028 xd_info[drive].ecc = 0x0B; /* ecc length */
1031 xd_info[drive].control = geometry_table[n][4]; /* control byte */
1032 xd_setparam(CMD_XBSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,geometry_table[n][2],geometry_table[n][3],0x0B);
1033 xd_recalibrate(drive);
1036 /* xd_override_init_drive: this finds disk geometry in a "binary search" style, narrowing in on the "correct" number of heads
1037 etc. by trying values until it gets the highest successful value. Idea courtesy Salvador Abreu (spa@fct.unl.pt). */
1038 static void __init xd_override_init_drive (u8 drive)
1040 u16 min[] = { 0,0,0 },max[] = { 16,1024,64 },test[] = { 0,0,0 };
1043 if (xd_geo[3*drive])
1044 xd_manual_geo_set(drive);
1046 for (i = 0; i < 3; i++) {
1047 while (min[i] != max[i] - 1) {
1048 test[i] = (min[i] + max[i]) / 2;
1049 xd_build(cmdblk,CMD_SEEK,drive,(u8) test[0],(u16) test[1],(u8) test[2],0,0);
1050 if (!xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 2))
1057 xd_info[drive].heads = (u8) min[0] + 1;
1058 xd_info[drive].cylinders = (u16) min[1] + 1;
1059 xd_info[drive].sectors = (u8) min[2] + 1;
1061 xd_info[drive].control = 0;
1064 /* xd_setup: initialise controller from command line parameters */
1065 void __init do_xd_setup (int *integers)
1067 switch (integers[0]) {
1068 case 4: if (integers[4] < 0)
1070 else if (integers[4] < 8)
1071 xd_dma = integers[4];
1072 case 3: if ((integers[3] > 0) && (integers[3] <= 0x3FC))
1073 xd_iobase = integers[3];
1074 case 2: if ((integers[2] > 0) && (integers[2] < 16))
1075 xd_irq = integers[2];
1076 case 1: xd_override = 1;
1077 if ((integers[1] >= 0) && (integers[1] < (sizeof(xd_sigs) / sizeof(xd_sigs[0]))))
1078 xd_type = integers[1];
1080 default:printk(KERN_ERR "xd: too many parameters for xd\n");
1082 xd_maxsectors = 0x01;
1085 /* xd_setparam: set the drive characteristics */
1086 static void __init xd_setparam (u8 command,u8 drive,u8 heads,u16 cylinders,u16 rwrite,u16 wprecomp,u8 ecc)
1090 xd_build(cmdblk,command,drive,0,0,0,0,0);
1091 cmdblk[6] = (u8) (cylinders >> 8) & 0x03;
1092 cmdblk[7] = (u8) (cylinders & 0xFF);
1093 cmdblk[8] = heads & 0x1F;
1094 cmdblk[9] = (u8) (rwrite >> 8) & 0x03;
1095 cmdblk[10] = (u8) (rwrite & 0xFF);
1096 cmdblk[11] = (u8) (wprecomp >> 8) & 0x03;
1097 cmdblk[12] = (u8) (wprecomp & 0xFF);
1100 /* Some controllers require geometry info as data, not command */
1102 if (xd_command(cmdblk,PIO_MODE,0,&cmdblk[6],0,XD_TIMEOUT * 2))
1103 printk(KERN_WARNING "xd: error setting characteristics for xd%c\n", 'a'+drive);
1108 static int xd[5] = { -1,-1,-1,-1, };
1110 MODULE_PARM(xd, "1-4i");
1111 MODULE_PARM(xd_geo, "3-6i");
1112 MODULE_PARM(nodma, "i");
1114 MODULE_LICENSE("GPL");
1116 static void xd_done (void)
1118 blksize_size[MAJOR_NR] = NULL;
1119 blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
1120 blk_size[MAJOR_NR] = NULL;
1121 hardsect_size[MAJOR_NR] = NULL;
1122 read_ahead[MAJOR_NR] = 0;
1123 del_gendisk(&xd_gendisk);
1124 release_region(xd_iobase,4);
1127 int init_module(void)
1132 for (i = 4; i > 0; i--)
1133 if(((xd[i] = xd[i-1]) >= 0) && !count)
1139 if (error) return error;
1141 printk(KERN_INFO "XD: Loaded as a module.\n");
1143 /* no drives detected - unload module */
1144 devfs_unregister_blkdev(MAJOR_NR, "xd");
1152 void cleanup_module(void)
1154 devfs_unregister_blkdev(MAJOR_NR, "xd");
1156 devfs_unregister(devfs_handle);
1158 free_irq(xd_irq, NULL);
1161 xd_dma_mem_free((unsigned long)xd_dma_buffer, xd_maxsectors * 0x200);
1166 static int __init xd_setup (char *str)
1169 get_options (str, ARRAY_SIZE (ints), ints);
1174 /* xd_manual_geo_init: initialise drive geometry from command line parameters
1175 (used only for WD drives) */
1176 static int __init xd_manual_geo_init (char *str)
1178 int i, integers[1 + 3*XD_MAXDRIVES];
1180 get_options (str, ARRAY_SIZE (integers), integers);
1181 if (integers[0]%3 != 0) {
1182 printk(KERN_ERR "xd: incorrect number of parameters for xd_geo\n");
1185 for (i = 0; (i < integers[0]) && (i < 3*XD_MAXDRIVES); i++)
1186 xd_geo[i] = integers[i+1];
1190 __setup ("xd=", xd_setup);
1191 __setup ("xd_geo=", xd_manual_geo_init);