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/interrupt.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/wait.h>
48 #include <linux/devfs_fs_kernel.h>
49 #include <linux/blkdev.h>
50 #include <linux/blkpg.h>
52 #include <asm/system.h>
54 #include <asm/uaccess.h>
59 static void __init do_xd_setup (int *integers);
61 static int xd[5] = { -1,-1,-1,-1, };
64 #define XD_DONT_USE_DMA 0 /* Initial value. may be overriden using
65 "nodma" module option */
66 #define XD_INIT_DISK_DELAY (30*HZ/1000) /* 30 ms delay during disk initialization */
68 /* Above may need to be increased if a problem with the 2nd drive detection
69 (ST11M controller) or resetting a controller (WD) appears */
71 XD_INFO xd_info[XD_MAXDRIVES];
73 /* If you try this driver and find that your card is not detected by the driver at bootup, you need to add your BIOS
74 signature and details to the following list of signatures. A BIOS signature is a string embedded into the first
75 few bytes of your controller's on-board ROM BIOS. To find out what yours is, use something like MS-DOS's DEBUG
76 command. Run DEBUG, and then you can examine your BIOS signature with:
80 where xxxx is the segment of your controller (like C800 or D000 or something). On the ASCII dump at the right, you should
81 be able to see a string mentioning the manufacturer's copyright etc. Add this string into the table below. The parameters
82 in the table are, in order:
84 offset ; this is the offset (in bytes) from the start of your ROM where the signature starts
85 signature ; this is the actual text of the signature
86 xd_?_init_controller ; this is the controller init routine used by your controller
87 xd_?_init_drive ; this is the drive init routine used by your controller
89 The controllers directly supported at the moment are: DTC 5150x, WD 1004A27X, ST11M/R and override. If your controller is
90 made by the same manufacturer as one of these, try using the same init routines as they do. If that doesn't work, your
91 best bet is to use the "override" routines. These routines use a "portable" method of getting the disk's geometry, and
92 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>.
94 NOTE: You can now specify your XT controller's parameters from the command line in the form xd=TYPE,IRQ,IO,DMA. The driver
95 should be able to detect your drive's geometry from this info. (eg: xd=0,5,0x320,3 is the "standard"). */
98 #define xd_dma_mem_alloc(size) __get_dma_pages(GFP_KERNEL,get_order(size))
99 #define xd_dma_mem_free(addr, size) free_pages(addr, get_order(size))
100 static char *xd_dma_buffer = 0;
102 static XD_SIGNATURE xd_sigs[] __initdata = {
103 { 0x0000,"Override geometry handler",NULL,xd_override_init_drive,"n unknown" }, /* Pat Mackinlay, pat@it.com.au */
104 { 0x0008,"[BXD06 (C) DTC 17-MAY-1985]",xd_dtc_init_controller,xd_dtc5150cx_init_drive," DTC 5150CX" }, /* Andrzej Krzysztofowicz, ankry@mif.pg.gda.pl */
105 { 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 */
106 { 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 */
107 { 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 */
108 { 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 */
109 { 0x0015,"SEAGATE ST11 BIOS REVISION",xd_seagate_init_controller,xd_seagate_init_drive," Seagate ST11M/R" }, /* Salvador Abreu, spa@fct.unl.pt */
110 { 0x0010,"ST11R BIOS",xd_seagate_init_controller,xd_seagate_init_drive," Seagate ST11M/R" }, /* Risto Kankkunen, risto.kankkunen@cs.helsinki.fi */
111 { 0x0010,"ST11 BIOS v1.7",xd_seagate_init_controller,xd_seagate_init_drive," Seagate ST11R" }, /* Alan Hourihane, alanh@fairlite.demon.co.uk */
112 { 0x1000,"(c)Copyright 1987 SMS",xd_omti_init_controller,xd_omti_init_drive,"n OMTI 5520" }, /* Dirk Melchers, dirk@merlin.nbg.sub.org */
113 { 0x0006,"COPYRIGHT XEBEC (C) 1984",xd_xebec_init_controller,xd_xebec_init_drive," XEBEC" }, /* Andrzej Krzysztofowicz, ankry@mif.pg.gda.pl */
114 { 0x0008,"(C) Copyright 1984 Western Digital Corp", xd_wd_init_controller, xd_wd_init_drive," Western Dig. 1002s-wx2" },
115 { 0x0008,"(C) Copyright 1986 Western Digital Corporation", xd_wd_init_controller, xd_wd_init_drive," 1986 Western Digital" }, /* jfree@sovereign.org */
118 static unsigned int xd_bases[] __initdata =
120 0xC8000, 0xCA000, 0xCC000,
121 0xCE000, 0xD0000, 0xD2000,
122 0xD4000, 0xD6000, 0xD8000,
123 0xDA000, 0xDC000, 0xDE000,
127 static spinlock_t xd_lock = SPIN_LOCK_UNLOCKED;
129 static struct gendisk *xd_gendisk[2];
131 static struct block_device_operations xd_fops = {
132 .owner = THIS_MODULE,
135 static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int);
136 static u_char xd_drives, xd_irq = 5, xd_dma = 3, xd_maxsectors;
137 static u_char xd_override __initdata = 0, xd_type __initdata = 0;
138 static u_short xd_iobase = 0x320;
139 static int xd_geo[XD_MAXDRIVES*3] __initdata = { 0, };
141 static volatile int xdc_busy;
142 static struct timer_list xd_watchdog_int;
144 static volatile u_char xd_error;
145 static int nodma = XD_DONT_USE_DMA;
147 static struct request_queue *xd_queue;
149 /* xd_init: register the block device number and set up pointer tables */
150 static int __init xd_init(void)
153 unsigned int address;
159 for (i = 4; i > 0; i--)
160 if (((xd[i] = xd[i-1]) >= 0) && !count)
167 init_timer (&xd_watchdog_int); xd_watchdog_int.function = xd_watchdog;
170 xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
171 if (!xd_dma_buffer) {
172 printk(KERN_ERR "xd: Out of memory.\n");
177 if (register_blkdev(XT_DISK_MAJOR, "xd"))
181 xd_queue = blk_init_queue(do_xd_request, &xd_lock);
186 if (xd_detect(&controller,&address)) {
188 printk("Detected a%s controller (type %d) at address %06x\n",
189 xd_sigs[controller].name,controller,address);
190 if (!request_region(xd_iobase,4,"xd")) {
191 printk("xd: Ports at 0x%x are not available\n",
196 xd_sigs[controller].init_controller(address);
197 xd_drives = xd_initdrives(xd_sigs[controller].init_drive);
199 printk("Detected %d hard drive%s (using IRQ%d & DMA%d)\n",
200 xd_drives,xd_drives == 1 ? "" : "s",xd_irq,xd_dma);
207 for (i = 0; i < xd_drives; i++) {
208 XD_INFO *p = &xd_info[i];
209 struct gendisk *disk = alloc_disk(64);
213 disk->major = XT_DISK_MAJOR;
214 disk->first_minor = i<<6;
215 sprintf(disk->disk_name, "xd%c", i+'a');
216 disk->fops = &xd_fops;
217 disk->private_data = p;
218 disk->queue = xd_queue;
219 set_capacity(disk, p->heads * p->cylinders * p->sectors);
220 printk(" %s: CHS=%d/%d/%d\n", disk->disk_name,
221 p->cylinders, p->heads, p->sectors);
222 xd_gendisk[i] = disk;
226 if (request_irq(xd_irq,xd_interrupt_handler, 0, "XT hard disk", NULL)) {
227 printk("xd: unable to get IRQ%d\n",xd_irq);
231 if (request_dma(xd_dma,"xd")) {
232 printk("xd: unable to get DMA%d\n",xd_dma);
236 /* xd_maxsectors depends on controller - so set after detection */
237 blk_queue_max_sectors(xd_queue, xd_maxsectors);
239 for (i = 0; i < xd_drives; i++)
240 add_disk(xd_gendisk[i]);
245 free_irq(xd_irq, NULL);
247 for (i = 0; i < xd_drives; i++)
248 put_disk(xd_gendisk[i]);
250 release_region(xd_iobase,4);
253 blk_cleanup_queue(xd_queue);
255 unregister_blkdev(XT_DISK_MAJOR, "xd");
258 xd_dma_mem_free((unsigned long)xd_dma_buffer,
259 xd_maxsectors * 0x200);
264 put_disk(xd_gendisk[i]);
268 /* xd_detect: scan the possible BIOS ROM locations for the signature strings */
269 static u_char __init xd_detect (u_char *controller, unsigned int *address)
271 u_char i,j,found = 0;
275 *controller = xd_type;
280 for (i = 0; i < (sizeof(xd_bases) / sizeof(xd_bases[0])) && !found; i++)
281 for (j = 1; j < (sizeof(xd_sigs) / sizeof(xd_sigs[0])) && !found; j++)
282 if (isa_check_signature(xd_bases[i] + xd_sigs[j].offset,xd_sigs[j].string,strlen(xd_sigs[j].string))) {
285 *address = xd_bases[i];
291 /* do_xd_request: handle an incoming request */
292 static void do_xd_request (request_queue_t * q)
299 while ((req = elv_next_request(q)) != NULL) {
300 unsigned block = req->sector;
301 unsigned count = req->nr_sectors;
302 int rw = rq_data_dir(req);
303 XD_INFO *disk = req->rq_disk->private_data;
307 if (!(req->flags & REQ_CMD)) {
311 if (block + count > get_capacity(req->rq_disk)) {
315 if (rw != READ && rw != WRITE) {
316 printk("do_xd_request: unknown request\n");
320 for (retry = 0; (retry < XD_RETRIES) && !res; retry++)
321 res = xd_readwrite(rw, disk, req->buffer, block, count);
322 end_request(req, res); /* wrap up, 0 = fail, 1 = success */
326 /* xd_ioctl: handle device ioctl's */
327 static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg)
329 XD_INFO *p = inode->i_bdev->bd_disk->private_data;
334 struct hd_geometry g;
335 struct hd_geometry *geometry = (struct hd_geometry *) arg;
337 g.sectors = p->sectors;
338 g.cylinders = p->cylinders;
339 g.start = get_start_sect(inode->i_bdev);
340 return copy_to_user(geometry, &g, sizeof g) ? -EFAULT : 0;
343 if (!capable(CAP_SYS_ADMIN)) return -EACCES;
344 if (xdc_busy) return -EBUSY;
346 if (nodma && xd_dma_buffer) {
347 xd_dma_mem_free((unsigned long)xd_dma_buffer,
348 xd_maxsectors * 0x200);
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 nodma = XD_DONT_USE_DMA;
359 return put_user(!nodma, (long *) arg);
360 case HDIO_GET_MULTCOUNT:
361 return put_user(xd_maxsectors, (long *) arg);
367 /* xd_readwrite: handle a read/write request */
368 static int xd_readwrite (u_char operation,XD_INFO *p,char *buffer,u_int block,u_int count)
371 u_char cmdblk[6],sense[4];
372 u_short track,cylinder;
373 u_char head,sector,control,mode = PIO_MODE,temp;
377 #ifdef DEBUG_READWRITE
378 printk("xd_readwrite: operation = %s, drive = %d, buffer = 0x%X, block = %d, count = %d\n",operation == READ ? "read" : "write",drive,buffer,block,count);
379 #endif /* DEBUG_READWRITE */
381 spin_unlock_irq(&xd_lock);
383 control = p->control;
385 xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
387 temp = count < xd_maxsectors ? count : xd_maxsectors;
389 track = block / p->sectors;
390 head = track % p->heads;
391 cylinder = track / p->heads;
392 sector = block % p->sectors;
394 #ifdef DEBUG_READWRITE
395 printk("xd_readwrite: drive = %d, head = %d, cylinder = %d, sector = %d, count = %d\n",drive,head,cylinder,sector,temp);
396 #endif /* DEBUG_READWRITE */
399 mode = xd_setup_dma(operation == READ ? DMA_MODE_READ : DMA_MODE_WRITE,(u_char *)(xd_dma_buffer),temp * 0x200);
400 real_buffer = &xd_dma_buffer;
401 for (i=0; i < (temp * 0x200); i++)
402 xd_dma_buffer[i] = buffer[i];
405 real_buffer = &buffer;
407 xd_build(cmdblk,operation == READ ? CMD_READ : CMD_WRITE,drive,head,cylinder,sector,temp & 0xFF,control);
409 switch (xd_command(cmdblk,mode,(u_char *)(*real_buffer),(u_char *)(*real_buffer),sense,XD_TIMEOUT)) {
411 printk("xd%c: %s timeout, recalibrating drive\n",'a'+drive,(operation == READ ? "read" : "write"));
412 xd_recalibrate(drive);
413 spin_lock_irq(&xd_lock);
416 if (sense[0] & 0x30) {
417 printk("xd%c: %s - ",'a'+drive,(operation == READ ? "reading" : "writing"));
418 switch ((sense[0] & 0x30) >> 4) {
419 case 0: printk("drive error, code = 0x%X",sense[0] & 0x0F);
421 case 1: printk("controller error, code = 0x%X",sense[0] & 0x0F);
423 case 2: printk("command error, code = 0x%X",sense[0] & 0x0F);
425 case 3: printk("miscellaneous error, code = 0x%X",sense[0] & 0x0F);
430 printk(" - CHS = %d/%d/%d\n",((sense[2] & 0xC0) << 2) | sense[3],sense[1] & 0x1F,sense[2] & 0x3F);
431 /* reported drive number = (sense[1] & 0xE0) >> 5 */
433 printk(" - no valid disk address\n");
434 spin_lock_irq(&xd_lock);
438 for (i=0; i < (temp * 0x200); i++)
439 buffer[i] = xd_dma_buffer[i];
441 count -= temp, buffer += temp * 0x200, block += temp;
443 spin_lock_irq(&xd_lock);
447 /* xd_recalibrate: recalibrate a given drive and reset controller if necessary */
448 static void xd_recalibrate (u_char drive)
452 xd_build(cmdblk,CMD_RECALIBRATE,drive,0,0,0,0,0);
453 if (xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 8))
454 printk("xd%c: warning! error recalibrating, controller may be unstable\n", 'a'+drive);
457 /* xd_interrupt_handler: interrupt service routine */
458 static irqreturn_t xd_interrupt_handler(int irq, void *dev_id,
459 struct pt_regs *regs)
461 if (inb(XD_STATUS) & STAT_INTERRUPT) { /* check if it was our device */
463 printk("xd_interrupt_handler: interrupt detected\n");
464 #endif /* DEBUG_OTHER */
465 outb(0,XD_CONTROL); /* acknowledge interrupt */
466 wake_up(&xd_wait_int); /* and wake up sleeping processes */
470 printk("xd: unexpected interrupt\n");
474 /* xd_setup_dma: set up the DMA controller for a data transfer */
475 static u_char xd_setup_dma (u_char mode,u_char *buffer,u_int count)
481 if (((unsigned long) buffer & 0xFFFF0000) != (((unsigned long) buffer + count) & 0xFFFF0000)) {
483 printk("xd_setup_dma: using PIO, transfer overlaps 64k boundary\n");
484 #endif /* DEBUG_OTHER */
490 clear_dma_ff(xd_dma);
491 set_dma_mode(xd_dma,mode);
492 set_dma_addr(xd_dma, (unsigned long) buffer);
493 set_dma_count(xd_dma,count);
497 return (DMA_MODE); /* use DMA and INT */
500 /* xd_build: put stuff into an array in a format suitable for the controller */
501 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)
504 cmdblk[1] = ((drive & 0x07) << 5) | (head & 0x1F);
505 cmdblk[2] = ((cylinder & 0x300) >> 2) | (sector & 0x3F);
506 cmdblk[3] = cylinder & 0xFF;
513 static void xd_watchdog (unsigned long unused)
516 wake_up(&xd_wait_int);
519 /* xd_waitport: waits until port & mask == flags or a timeout occurs. return 1 for a timeout */
520 static inline u_char xd_waitport (u_short port,u_char flags,u_char mask,u_long timeout)
522 u_long expiry = jiffies + timeout;
526 while ((success = ((inb(port) & mask) != flags)) && time_before(jiffies, expiry)) {
527 set_current_state(TASK_UNINTERRUPTIBLE);
534 static inline u_int xd_wait_for_IRQ (void)
537 xd_watchdog_int.expires = jiffies + 8 * HZ;
538 add_timer(&xd_watchdog_int);
540 flags=claim_dma_lock();
542 release_dma_lock(flags);
544 sleep_on(&xd_wait_int);
545 del_timer(&xd_watchdog_int);
548 flags=claim_dma_lock();
550 release_dma_lock(flags);
553 printk("xd: missed IRQ - command aborted\n");
560 /* xd_command: handle all data transfers necessary for a single command */
561 static u_int xd_command (u_char *command,u_char mode,u_char *indata,u_char *outdata,u_char *sense,u_long timeout)
563 u_char cmdblk[6],csb,complete = 0;
566 printk("xd_command: command = 0x%X, mode = 0x%X, indata = 0x%X, outdata = 0x%X, sense = 0x%X\n",command,mode,indata,outdata,sense);
567 #endif /* DEBUG_COMMAND */
570 outb(mode,XD_CONTROL);
572 if (xd_waitport(XD_STATUS,STAT_SELECT,STAT_SELECT,timeout))
576 if (xd_waitport(XD_STATUS,STAT_READY,STAT_READY,timeout))
579 switch (inb(XD_STATUS) & (STAT_COMMAND | STAT_INPUT)) {
581 if (mode == DMA_MODE) {
582 if (xd_wait_for_IRQ())
585 outb(outdata ? *outdata++ : 0,XD_DATA);
588 if (mode == DMA_MODE) {
589 if (xd_wait_for_IRQ())
593 *indata++ = inb(XD_DATA);
598 outb(command ? *command++ : 0,XD_DATA);
600 case STAT_COMMAND | STAT_INPUT:
607 if (xd_waitport(XD_STATUS,0,STAT_SELECT,timeout)) /* wait until deselected */
610 if (csb & CSB_ERROR) { /* read sense data if error */
611 xd_build(cmdblk,CMD_SENSE,(csb & CSB_LUN) >> 5,0,0,0,0,0);
612 if (xd_command(cmdblk,0,sense,0,0,XD_TIMEOUT))
613 printk("xd: warning! sense command failed!\n");
617 printk("xd_command: completed with csb = 0x%X\n",csb);
618 #endif /* DEBUG_COMMAND */
620 return (csb & CSB_ERROR);
623 static u_char __init xd_initdrives (void (*init_drive)(u_char drive))
625 u_char cmdblk[6],i,count = 0;
627 for (i = 0; i < XD_MAXDRIVES; i++) {
628 xd_build(cmdblk,CMD_TESTREADY,i,0,0,0,0,0);
629 if (!xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 8)) {
630 set_current_state(TASK_INTERRUPTIBLE);
631 schedule_timeout(XD_INIT_DISK_DELAY);
636 set_current_state(TASK_INTERRUPTIBLE);
637 schedule_timeout(XD_INIT_DISK_DELAY);
643 static void __init xd_manual_geo_set (u_char drive)
645 xd_info[drive].heads = (u_char)(xd_geo[3 * drive + 1]);
646 xd_info[drive].cylinders = (u_short)(xd_geo[3 * drive]);
647 xd_info[drive].sectors = (u_char)(xd_geo[3 * drive + 2]);
650 static void __init xd_dtc_init_controller (unsigned int address)
654 case 0xC8000: break; /*initial: 0x320 */
655 case 0xCA000: xd_iobase = 0x324;
656 case 0xD0000: /*5150CX*/
657 case 0xD8000: break; /*5150CX & 5150XL*/
658 default: printk("xd_dtc_init_controller: unsupported BIOS address %06x\n",address);
661 xd_maxsectors = 0x01; /* my card seems to have trouble doing multi-block transfers? */
663 outb(0,XD_RESET); /* reset the controller */
667 static void __init xd_dtc5150cx_init_drive (u_char drive)
669 /* values from controller's BIOS - BIOS chip may be removed */
670 static u_short geometry_table[][4] = {
671 {0x200,8,0x200,0x100},
672 {0x267,2,0x267,0x267},
673 {0x264,4,0x264,0x80},
675 {0x132,2,0x80, 0x132},
679 {0x132,6,0x80, 0x100},
680 {0x200,6,0x100,0x100},
681 {0x264,2,0x264,0x80},
682 {0x280,4,0x280,0x100},
683 {0x2B9,3,0x2B9,0x2B9},
684 {0x2B9,5,0x2B9,0x2B9},
685 {0x280,6,0x280,0x100},
686 {0x132,4,0x132,0x0}};
690 n = (drive ? n : (n >> 2)) & 0x33;
691 n = (n | (n >> 2)) & 0x0F;
693 xd_manual_geo_set(drive);
696 xd_info[drive].heads = (u_char)(geometry_table[n][1]); /* heads */
697 xd_info[drive].cylinders = geometry_table[n][0]; /* cylinders */
698 xd_info[drive].sectors = 17; /* sectors */
700 xd_info[drive].rwrite = geometry_table[n][2]; /* reduced write */
701 xd_info[drive].precomp = geometry_table[n][3] /* write precomp */
702 xd_info[drive].ecc = 0x0B; /* ecc length */
706 printk("xd%c: undetermined drive geometry\n",'a'+drive);
709 xd_info[drive].control = 5; /* control byte */
710 xd_setparam(CMD_DTCSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,geometry_table[n][2],geometry_table[n][3],0x0B);
711 xd_recalibrate(drive);
714 static void __init xd_dtc_init_drive (u_char drive)
716 u_char cmdblk[6],buf[64];
718 xd_build(cmdblk,CMD_DTCGETGEOM,drive,0,0,0,0,0);
719 if (!xd_command(cmdblk,PIO_MODE,buf,0,0,XD_TIMEOUT * 2)) {
720 xd_info[drive].heads = buf[0x0A]; /* heads */
721 xd_info[drive].cylinders = ((u_short *) (buf))[0x04]; /* cylinders */
722 xd_info[drive].sectors = 17; /* sectors */
724 xd_manual_geo_set(drive);
726 xd_info[drive].rwrite = ((u_short *) (buf + 1))[0x05]; /* reduced write */
727 xd_info[drive].precomp = ((u_short *) (buf + 1))[0x06]; /* write precomp */
728 xd_info[drive].ecc = buf[0x0F]; /* ecc length */
730 xd_info[drive].control = 0; /* control byte */
732 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]);
733 xd_build(cmdblk,CMD_DTCSETSTEP,drive,0,0,0,0,7);
734 if (xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 2))
735 printk("xd_dtc_init_drive: error setting step rate for xd%c\n", 'a'+drive);
738 printk("xd_dtc_init_drive: error reading geometry for xd%c\n", 'a'+drive);
741 static void __init xd_wd_init_controller (unsigned int address)
745 case 0xC8000: break; /*initial: 0x320 */
746 case 0xCA000: xd_iobase = 0x324; break;
747 case 0xCC000: xd_iobase = 0x328; break;
748 case 0xCE000: xd_iobase = 0x32C; break;
749 case 0xD0000: xd_iobase = 0x328; break; /* ? */
750 case 0xD8000: xd_iobase = 0x32C; break; /* ? */
751 default: printk("xd_wd_init_controller: unsupported BIOS address %06x\n",address);
754 xd_maxsectors = 0x01; /* this one doesn't wrap properly either... */
756 outb(0,XD_RESET); /* reset the controller */
758 set_current_state(TASK_UNINTERRUPTIBLE);
759 schedule_timeout(XD_INIT_DISK_DELAY);
762 static void __init xd_wd_init_drive (u_char drive)
764 /* values from controller's BIOS - BIOS may be disabled */
765 static u_short geometry_table[][4] = {
766 {0x264,4,0x1C2,0x1C2}, /* common part */
768 {0x267,2,0x1C2,0x1C2},
769 {0x267,4,0x1C2,0x1C2},
771 {0x334,6,0x335,0x335}, /* 1004 series RLL */
772 {0x30E,4,0x30F,0x3DC},
773 {0x30E,2,0x30F,0x30F},
774 {0x267,4,0x268,0x268},
776 {0x3D5,5,0x3D6,0x3D6}, /* 1002 series RLL */
777 {0x3DB,7,0x3DC,0x3DC},
778 {0x264,4,0x265,0x265},
779 {0x267,4,0x268,0x268}};
781 u_char cmdblk[6],buf[0x200];
782 u_char n = 0,rll,jumper_state,use_jumper_geo;
783 u_char wd_1002 = (xd_sigs[xd_type].string[7] == '6');
785 jumper_state = ~(inb(0x322));
786 if (jumper_state & 0x40)
788 rll = (jumper_state & 0x30) ? (0x04 << wd_1002) : 0;
789 xd_build(cmdblk,CMD_READ,drive,0,0,0,1,0);
790 if (!xd_command(cmdblk,PIO_MODE,buf,0,0,XD_TIMEOUT * 2)) {
791 xd_info[drive].heads = buf[0x1AF]; /* heads */
792 xd_info[drive].cylinders = ((u_short *) (buf + 1))[0xD6]; /* cylinders */
793 xd_info[drive].sectors = 17; /* sectors */
795 xd_manual_geo_set(drive);
797 xd_info[drive].rwrite = ((u_short *) (buf))[0xD8]; /* reduced write */
798 xd_info[drive].wprecomp = ((u_short *) (buf))[0xDA]; /* write precomp */
799 xd_info[drive].ecc = buf[0x1B4]; /* ecc length */
801 xd_info[drive].control = buf[0x1B5]; /* control byte */
802 use_jumper_geo = !(xd_info[drive].heads) || !(xd_info[drive].cylinders);
803 if (xd_geo[3*drive]) {
804 xd_manual_geo_set(drive);
805 xd_info[drive].control = rll ? 7 : 5;
807 else if (use_jumper_geo) {
808 n = (((jumper_state & 0x0F) >> (drive << 1)) & 0x03) | rll;
809 xd_info[drive].cylinders = geometry_table[n][0];
810 xd_info[drive].heads = (u_char)(geometry_table[n][1]);
811 xd_info[drive].control = rll ? 7 : 5;
813 xd_info[drive].rwrite = geometry_table[n][2];
814 xd_info[drive].wprecomp = geometry_table[n][3];
815 xd_info[drive].ecc = 0x0B;
820 xd_setparam(CMD_WDSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,
821 geometry_table[n][2],geometry_table[n][3],0x0B);
823 xd_setparam(CMD_WDSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,
824 ((u_short *) (buf))[0xD8],((u_short *) (buf))[0xDA],buf[0x1B4]);
826 /* 1002 based RLL controller requests converted addressing, but reports physical
827 (physical 26 sec., logical 17 sec.)
830 if ((xd_info[drive].cylinders *= 26,
831 xd_info[drive].cylinders /= 17) > 1023)
832 xd_info[drive].cylinders = 1023; /* 1024 ? */
834 xd_info[drive].rwrite *= 26;
835 xd_info[drive].rwrite /= 17;
836 xd_info[drive].wprecomp *= 26
837 xd_info[drive].wprecomp /= 17;
842 printk("xd_wd_init_drive: error reading geometry for xd%c\n",'a'+drive);
846 static void __init xd_seagate_init_controller (unsigned int address)
850 case 0xC8000: break; /*initial: 0x320 */
851 case 0xD0000: xd_iobase = 0x324; break;
852 case 0xD8000: xd_iobase = 0x328; break;
853 case 0xE0000: xd_iobase = 0x32C; break;
854 default: printk("xd_seagate_init_controller: unsupported BIOS address %06x\n",address);
857 xd_maxsectors = 0x40;
859 outb(0,XD_RESET); /* reset the controller */
862 static void __init xd_seagate_init_drive (u_char drive)
864 u_char cmdblk[6],buf[0x200];
866 xd_build(cmdblk,CMD_ST11GETGEOM,drive,0,0,0,1,0);
867 if (!xd_command(cmdblk,PIO_MODE,buf,0,0,XD_TIMEOUT * 2)) {
868 xd_info[drive].heads = buf[0x04]; /* heads */
869 xd_info[drive].cylinders = (buf[0x02] << 8) | buf[0x03]; /* cylinders */
870 xd_info[drive].sectors = buf[0x05]; /* sectors */
871 xd_info[drive].control = 0; /* control byte */
874 printk("xd_seagate_init_drive: error reading geometry from xd%c\n", 'a'+drive);
877 /* Omti support courtesy Dirk Melchers */
878 static void __init xd_omti_init_controller (unsigned int address)
882 case 0xC8000: break; /*initial: 0x320 */
883 case 0xD0000: xd_iobase = 0x324; break;
884 case 0xD8000: xd_iobase = 0x328; break;
885 case 0xE0000: xd_iobase = 0x32C; break;
886 default: printk("xd_omti_init_controller: unsupported BIOS address %06x\n",address);
890 xd_maxsectors = 0x40;
892 outb(0,XD_RESET); /* reset the controller */
895 static void __init xd_omti_init_drive (u_char drive)
897 /* gets infos from drive */
898 xd_override_init_drive(drive);
900 /* set other parameters, Hardcoded, not that nice :-) */
901 xd_info[drive].control = 2;
904 /* Xebec support (AK) */
905 static void __init xd_xebec_init_controller (unsigned int address)
907 /* iobase may be set manually in range 0x300 - 0x33C
908 irq may be set manually to 2(9),3,4,5,6,7
909 dma may be set manually to 1,2,3
910 (How to detect them ???)
911 BIOS address may be set manually in range 0x0 - 0xF8000
912 If you need non-standard settings use the xd=... command */
916 case 0xC8000: /* initially: xd_iobase==0x320 */
926 default: printk("xd_xebec_init_controller: unsupported BIOS address %06x\n",address);
930 xd_maxsectors = 0x01;
931 outb(0,XD_RESET); /* reset the controller */
933 set_current_state(TASK_UNINTERRUPTIBLE);
934 schedule_timeout(XD_INIT_DISK_DELAY);
937 static void __init xd_xebec_init_drive (u_char drive)
939 /* values from controller's BIOS - BIOS chip may be removed */
940 static u_short geometry_table[][5] = {
941 {0x132,4,0x080,0x080,0x7},
942 {0x132,4,0x080,0x080,0x17},
943 {0x264,2,0x100,0x100,0x7},
944 {0x264,2,0x100,0x100,0x17},
945 {0x132,8,0x080,0x080,0x7},
946 {0x132,8,0x080,0x080,0x17},
947 {0x264,4,0x100,0x100,0x6},
948 {0x264,4,0x100,0x100,0x17},
949 {0x2BC,5,0x2BC,0x12C,0x6},
950 {0x3A5,4,0x3A5,0x3A5,0x7},
951 {0x26C,6,0x26C,0x26C,0x7},
952 {0x200,8,0x200,0x100,0x17},
953 {0x400,5,0x400,0x400,0x7},
954 {0x400,6,0x400,0x400,0x7},
955 {0x264,8,0x264,0x200,0x17},
956 {0x33E,7,0x33E,0x200,0x7}};
959 n = inb(XD_JUMPER) & 0x0F; /* BIOS's drive number: same geometry
960 is assumed for BOTH drives */
962 xd_manual_geo_set(drive);
964 xd_info[drive].heads = (u_char)(geometry_table[n][1]); /* heads */
965 xd_info[drive].cylinders = geometry_table[n][0]; /* cylinders */
966 xd_info[drive].sectors = 17; /* sectors */
968 xd_info[drive].rwrite = geometry_table[n][2]; /* reduced write */
969 xd_info[drive].precomp = geometry_table[n][3] /* write precomp */
970 xd_info[drive].ecc = 0x0B; /* ecc length */
973 xd_info[drive].control = geometry_table[n][4]; /* control byte */
974 xd_setparam(CMD_XBSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,geometry_table[n][2],geometry_table[n][3],0x0B);
975 xd_recalibrate(drive);
978 /* xd_override_init_drive: this finds disk geometry in a "binary search" style, narrowing in on the "correct" number of heads
979 etc. by trying values until it gets the highest successful value. Idea courtesy Salvador Abreu (spa@fct.unl.pt). */
980 static void __init xd_override_init_drive (u_char drive)
982 u_short min[] = { 0,0,0 },max[] = { 16,1024,64 },test[] = { 0,0,0 };
986 xd_manual_geo_set(drive);
988 for (i = 0; i < 3; i++) {
989 while (min[i] != max[i] - 1) {
990 test[i] = (min[i] + max[i]) / 2;
991 xd_build(cmdblk,CMD_SEEK,drive,(u_char) test[0],(u_short) test[1],(u_char) test[2],0,0);
992 if (!xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 2))
999 xd_info[drive].heads = (u_char) min[0] + 1;
1000 xd_info[drive].cylinders = (u_short) min[1] + 1;
1001 xd_info[drive].sectors = (u_char) min[2] + 1;
1003 xd_info[drive].control = 0;
1006 /* xd_setup: initialise controller from command line parameters */
1007 static void __init do_xd_setup (int *integers)
1009 switch (integers[0]) {
1010 case 4: if (integers[4] < 0)
1012 else if (integers[4] < 8)
1013 xd_dma = integers[4];
1014 case 3: if ((integers[3] > 0) && (integers[3] <= 0x3FC))
1015 xd_iobase = integers[3];
1016 case 2: if ((integers[2] > 0) && (integers[2] < 16))
1017 xd_irq = integers[2];
1018 case 1: xd_override = 1;
1019 if ((integers[1] >= 0) && (integers[1] < (sizeof(xd_sigs) / sizeof(xd_sigs[0]))))
1020 xd_type = integers[1];
1022 default:printk("xd: too many parameters for xd\n");
1024 xd_maxsectors = 0x01;
1027 /* xd_setparam: set the drive characteristics */
1028 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)
1032 xd_build(cmdblk,command,drive,0,0,0,0,0);
1033 cmdblk[6] = (u_char) (cylinders >> 8) & 0x03;
1034 cmdblk[7] = (u_char) (cylinders & 0xFF);
1035 cmdblk[8] = heads & 0x1F;
1036 cmdblk[9] = (u_char) (rwrite >> 8) & 0x03;
1037 cmdblk[10] = (u_char) (rwrite & 0xFF);
1038 cmdblk[11] = (u_char) (wprecomp >> 8) & 0x03;
1039 cmdblk[12] = (u_char) (wprecomp & 0xFF);
1042 /* Some controllers require geometry info as data, not command */
1044 if (xd_command(cmdblk,PIO_MODE,0,&cmdblk[6],0,XD_TIMEOUT * 2))
1045 printk("xd: error setting characteristics for xd%c\n", 'a'+drive);
1051 MODULE_PARM(xd, "1-4i");
1052 MODULE_PARM(xd_geo, "3-6i");
1053 MODULE_PARM(nodma, "i");
1055 MODULE_LICENSE("GPL");
1057 void cleanup_module(void)
1060 unregister_blkdev(XT_DISK_MAJOR, "xd");
1061 for (i = 0; i < xd_drives; i++) {
1062 del_gendisk(xd_gendisk[i]);
1063 put_disk(xd_gendisk[i]);
1065 blk_cleanup_queue(xd_queue);
1066 release_region(xd_iobase,4);
1069 free_irq(xd_irq, NULL);
1072 xd_dma_mem_free((unsigned long)xd_dma_buffer, xd_maxsectors * 0x200);
1077 static int __init xd_setup (char *str)
1080 get_options (str, ARRAY_SIZE (ints), ints);
1085 /* xd_manual_geo_init: initialise drive geometry from command line parameters
1086 (used only for WD drives) */
1087 static int __init xd_manual_geo_init (char *str)
1089 int i, integers[1 + 3*XD_MAXDRIVES];
1091 get_options (str, ARRAY_SIZE (integers), integers);
1092 if (integers[0]%3 != 0) {
1093 printk("xd: incorrect number of parameters for xd_geo\n");
1096 for (i = 0; (i < integers[0]) && (i < 3*XD_MAXDRIVES); i++)
1097 xd_geo[i] = integers[i+1];
1101 __setup ("xd=", xd_setup);
1102 __setup ("xd_geo=", xd_manual_geo_init);
1106 module_init(xd_init)