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/blkdev.h>
49 #include <linux/blkpg.h>
51 #include <asm/system.h>
53 #include <asm/uaccess.h>
58 static void __init do_xd_setup (int *integers);
60 static int xd[5] = { -1,-1,-1,-1, };
63 #define XD_DONT_USE_DMA 0 /* Initial value. may be overriden using
64 "nodma" module option */
65 #define XD_INIT_DISK_DELAY (30*HZ/1000) /* 30 ms delay during disk initialization */
67 /* Above may need to be increased if a problem with the 2nd drive detection
68 (ST11M controller) or resetting a controller (WD) appears */
70 XD_INFO xd_info[XD_MAXDRIVES];
72 /* If you try this driver and find that your card is not detected by the driver at bootup, you need to add your BIOS
73 signature and details to the following list of signatures. A BIOS signature is a string embedded into the first
74 few bytes of your controller's on-board ROM BIOS. To find out what yours is, use something like MS-DOS's DEBUG
75 command. Run DEBUG, and then you can examine your BIOS signature with:
79 where xxxx is the segment of your controller (like C800 or D000 or something). On the ASCII dump at the right, you should
80 be able to see a string mentioning the manufacturer's copyright etc. Add this string into the table below. The parameters
81 in the table are, in order:
83 offset ; this is the offset (in bytes) from the start of your ROM where the signature starts
84 signature ; this is the actual text of the signature
85 xd_?_init_controller ; this is the controller init routine used by your controller
86 xd_?_init_drive ; this is the drive init routine used by your controller
88 The controllers directly supported at the moment are: DTC 5150x, WD 1004A27X, ST11M/R and override. If your controller is
89 made by the same manufacturer as one of these, try using the same init routines as they do. If that doesn't work, your
90 best bet is to use the "override" routines. These routines use a "portable" method of getting the disk's geometry, and
91 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>.
93 NOTE: You can now specify your XT controller's parameters from the command line in the form xd=TYPE,IRQ,IO,DMA. The driver
94 should be able to detect your drive's geometry from this info. (eg: xd=0,5,0x320,3 is the "standard"). */
97 #define xd_dma_mem_alloc(size) __get_dma_pages(GFP_KERNEL,get_order(size))
98 #define xd_dma_mem_free(addr, size) free_pages(addr, get_order(size))
99 static char *xd_dma_buffer = 0;
101 static XD_SIGNATURE xd_sigs[] __initdata = {
102 { 0x0000,"Override geometry handler",NULL,xd_override_init_drive,"n unknown" }, /* Pat Mackinlay, pat@it.com.au */
103 { 0x0008,"[BXD06 (C) DTC 17-MAY-1985]",xd_dtc_init_controller,xd_dtc5150cx_init_drive," DTC 5150CX" }, /* Andrzej Krzysztofowicz, ankry@mif.pg.gda.pl */
104 { 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 */
105 { 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 */
106 { 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 */
107 { 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 */
108 { 0x0015,"SEAGATE ST11 BIOS REVISION",xd_seagate_init_controller,xd_seagate_init_drive," Seagate ST11M/R" }, /* Salvador Abreu, spa@fct.unl.pt */
109 { 0x0010,"ST11R BIOS",xd_seagate_init_controller,xd_seagate_init_drive," Seagate ST11M/R" }, /* Risto Kankkunen, risto.kankkunen@cs.helsinki.fi */
110 { 0x0010,"ST11 BIOS v1.7",xd_seagate_init_controller,xd_seagate_init_drive," Seagate ST11R" }, /* Alan Hourihane, alanh@fairlite.demon.co.uk */
111 { 0x1000,"(c)Copyright 1987 SMS",xd_omti_init_controller,xd_omti_init_drive,"n OMTI 5520" }, /* Dirk Melchers, dirk@merlin.nbg.sub.org */
112 { 0x0006,"COPYRIGHT XEBEC (C) 1984",xd_xebec_init_controller,xd_xebec_init_drive," XEBEC" }, /* Andrzej Krzysztofowicz, ankry@mif.pg.gda.pl */
113 { 0x0008,"(C) Copyright 1984 Western Digital Corp", xd_wd_init_controller, xd_wd_init_drive," Western Dig. 1002s-wx2" },
114 { 0x0008,"(C) Copyright 1986 Western Digital Corporation", xd_wd_init_controller, xd_wd_init_drive," 1986 Western Digital" }, /* jfree@sovereign.org */
117 static unsigned int xd_bases[] __initdata =
119 0xC8000, 0xCA000, 0xCC000,
120 0xCE000, 0xD0000, 0xD2000,
121 0xD4000, 0xD6000, 0xD8000,
122 0xDA000, 0xDC000, 0xDE000,
126 static spinlock_t xd_lock = SPIN_LOCK_UNLOCKED;
128 static struct gendisk *xd_gendisk[2];
130 static struct block_device_operations xd_fops = {
131 .owner = THIS_MODULE,
134 static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int);
135 static u_char xd_drives, xd_irq = 5, xd_dma = 3, xd_maxsectors;
136 static u_char xd_override __initdata = 0, xd_type __initdata = 0;
137 static u_short xd_iobase = 0x320;
138 static int xd_geo[XD_MAXDRIVES*3] __initdata = { 0, };
140 static volatile int xdc_busy;
141 static struct timer_list xd_watchdog_int;
143 static volatile u_char xd_error;
144 static int nodma = XD_DONT_USE_DMA;
146 static struct request_queue *xd_queue;
148 /* xd_init: register the block device number and set up pointer tables */
149 static int __init xd_init(void)
152 unsigned int address;
158 for (i = 4; i > 0; i--)
159 if (((xd[i] = xd[i-1]) >= 0) && !count)
166 init_timer (&xd_watchdog_int); xd_watchdog_int.function = xd_watchdog;
169 xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
170 if (!xd_dma_buffer) {
171 printk(KERN_ERR "xd: Out of memory.\n");
176 if (register_blkdev(XT_DISK_MAJOR, "xd"))
180 xd_queue = blk_init_queue(do_xd_request, &xd_lock);
184 if (xd_detect(&controller,&address)) {
186 printk("Detected a%s controller (type %d) at address %06x\n",
187 xd_sigs[controller].name,controller,address);
188 if (!request_region(xd_iobase,4,"xd")) {
189 printk("xd: Ports at 0x%x are not available\n",
194 xd_sigs[controller].init_controller(address);
195 xd_drives = xd_initdrives(xd_sigs[controller].init_drive);
197 printk("Detected %d hard drive%s (using IRQ%d & DMA%d)\n",
198 xd_drives,xd_drives == 1 ? "" : "s",xd_irq,xd_dma);
205 for (i = 0; i < xd_drives; i++) {
206 XD_INFO *p = &xd_info[i];
207 struct gendisk *disk = alloc_disk(64);
211 disk->major = XT_DISK_MAJOR;
212 disk->first_minor = i<<6;
213 sprintf(disk->disk_name, "xd%c", i+'a');
214 sprintf(disk->devfs_name, "xd/target%d", i);
215 disk->fops = &xd_fops;
216 disk->private_data = p;
217 disk->queue = xd_queue;
218 set_capacity(disk, p->heads * p->cylinders * p->sectors);
219 printk(" %s: CHS=%d/%d/%d\n", disk->disk_name,
220 p->cylinders, p->heads, p->sectors);
221 xd_gendisk[i] = disk;
225 if (request_irq(xd_irq,xd_interrupt_handler, 0, "XT hard disk", NULL)) {
226 printk("xd: unable to get IRQ%d\n",xd_irq);
230 if (request_dma(xd_dma,"xd")) {
231 printk("xd: unable to get DMA%d\n",xd_dma);
235 /* xd_maxsectors depends on controller - so set after detection */
236 blk_queue_max_sectors(xd_queue, xd_maxsectors);
238 for (i = 0; i < xd_drives; i++)
239 add_disk(xd_gendisk[i]);
244 free_irq(xd_irq, NULL);
246 for (i = 0; i < xd_drives; i++)
247 put_disk(xd_gendisk[i]);
249 release_region(xd_iobase,4);
251 blk_cleanup_queue(xd_queue);
253 unregister_blkdev(XT_DISK_MAJOR, "xd");
256 xd_dma_mem_free((unsigned long)xd_dma_buffer,
257 xd_maxsectors * 0x200);
262 put_disk(xd_gendisk[i]);
266 /* xd_detect: scan the possible BIOS ROM locations for the signature strings */
267 static u_char __init xd_detect (u_char *controller, unsigned int *address)
269 u_char i,j,found = 0;
273 *controller = xd_type;
278 for (i = 0; i < (sizeof(xd_bases) / sizeof(xd_bases[0])) && !found; i++)
279 for (j = 1; j < (sizeof(xd_sigs) / sizeof(xd_sigs[0])) && !found; j++)
280 if (isa_check_signature(xd_bases[i] + xd_sigs[j].offset,xd_sigs[j].string,strlen(xd_sigs[j].string))) {
283 *address = xd_bases[i];
289 /* do_xd_request: handle an incoming request */
290 static void do_xd_request (request_queue_t * q)
297 while ((req = elv_next_request(q)) != NULL) {
298 unsigned block = req->sector;
299 unsigned count = req->nr_sectors;
300 int rw = rq_data_dir(req);
301 XD_INFO *disk = req->rq_disk->private_data;
305 if (!(req->flags & REQ_CMD)) {
309 if (block + count > get_capacity(req->rq_disk)) {
313 if (rw != READ && rw != WRITE) {
314 printk("do_xd_request: unknown request\n");
318 for (retry = 0; (retry < XD_RETRIES) && !res; retry++)
319 res = xd_readwrite(rw, disk, req->buffer, block, count);
320 end_request(req, res); /* wrap up, 0 = fail, 1 = success */
324 /* xd_ioctl: handle device ioctl's */
325 static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg)
327 XD_INFO *p = inode->i_bdev->bd_disk->private_data;
332 struct hd_geometry g;
333 struct hd_geometry *geometry = (struct hd_geometry *) arg;
335 g.sectors = p->sectors;
336 g.cylinders = p->cylinders;
337 g.start = get_start_sect(inode->i_bdev);
338 return copy_to_user(geometry, &g, sizeof g) ? -EFAULT : 0;
341 if (!capable(CAP_SYS_ADMIN)) return -EACCES;
342 if (xdc_busy) return -EBUSY;
344 if (nodma && xd_dma_buffer) {
345 xd_dma_mem_free((unsigned long)xd_dma_buffer,
346 xd_maxsectors * 0x200);
348 } else if (!nodma && !xd_dma_buffer) {
349 xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
350 if (!xd_dma_buffer) {
351 nodma = XD_DONT_USE_DMA;
357 return put_user(!nodma, (long *) arg);
358 case HDIO_GET_MULTCOUNT:
359 return put_user(xd_maxsectors, (long *) arg);
365 /* xd_readwrite: handle a read/write request */
366 static int xd_readwrite (u_char operation,XD_INFO *p,char *buffer,u_int block,u_int count)
369 u_char cmdblk[6],sense[4];
370 u_short track,cylinder;
371 u_char head,sector,control,mode = PIO_MODE,temp;
375 #ifdef DEBUG_READWRITE
376 printk("xd_readwrite: operation = %s, drive = %d, buffer = 0x%X, block = %d, count = %d\n",operation == READ ? "read" : "write",drive,buffer,block,count);
377 #endif /* DEBUG_READWRITE */
379 spin_unlock_irq(&xd_lock);
381 control = p->control;
383 xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
385 temp = count < xd_maxsectors ? count : xd_maxsectors;
387 track = block / p->sectors;
388 head = track % p->heads;
389 cylinder = track / p->heads;
390 sector = block % p->sectors;
392 #ifdef DEBUG_READWRITE
393 printk("xd_readwrite: drive = %d, head = %d, cylinder = %d, sector = %d, count = %d\n",drive,head,cylinder,sector,temp);
394 #endif /* DEBUG_READWRITE */
397 mode = xd_setup_dma(operation == READ ? DMA_MODE_READ : DMA_MODE_WRITE,(u_char *)(xd_dma_buffer),temp * 0x200);
398 real_buffer = &xd_dma_buffer;
399 for (i=0; i < (temp * 0x200); i++)
400 xd_dma_buffer[i] = buffer[i];
403 real_buffer = &buffer;
405 xd_build(cmdblk,operation == READ ? CMD_READ : CMD_WRITE,drive,head,cylinder,sector,temp & 0xFF,control);
407 switch (xd_command(cmdblk,mode,(u_char *)(*real_buffer),(u_char *)(*real_buffer),sense,XD_TIMEOUT)) {
409 printk("xd%c: %s timeout, recalibrating drive\n",'a'+drive,(operation == READ ? "read" : "write"));
410 xd_recalibrate(drive);
411 spin_lock_irq(&xd_lock);
414 if (sense[0] & 0x30) {
415 printk("xd%c: %s - ",'a'+drive,(operation == READ ? "reading" : "writing"));
416 switch ((sense[0] & 0x30) >> 4) {
417 case 0: printk("drive error, code = 0x%X",sense[0] & 0x0F);
419 case 1: printk("controller error, code = 0x%X",sense[0] & 0x0F);
421 case 2: printk("command error, code = 0x%X",sense[0] & 0x0F);
423 case 3: printk("miscellaneous error, code = 0x%X",sense[0] & 0x0F);
428 printk(" - CHS = %d/%d/%d\n",((sense[2] & 0xC0) << 2) | sense[3],sense[1] & 0x1F,sense[2] & 0x3F);
429 /* reported drive number = (sense[1] & 0xE0) >> 5 */
431 printk(" - no valid disk address\n");
432 spin_lock_irq(&xd_lock);
436 for (i=0; i < (temp * 0x200); i++)
437 buffer[i] = xd_dma_buffer[i];
439 count -= temp, buffer += temp * 0x200, block += temp;
441 spin_lock_irq(&xd_lock);
445 /* xd_recalibrate: recalibrate a given drive and reset controller if necessary */
446 static void xd_recalibrate (u_char drive)
450 xd_build(cmdblk,CMD_RECALIBRATE,drive,0,0,0,0,0);
451 if (xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 8))
452 printk("xd%c: warning! error recalibrating, controller may be unstable\n", 'a'+drive);
455 /* xd_interrupt_handler: interrupt service routine */
456 static irqreturn_t xd_interrupt_handler(int irq, void *dev_id,
457 struct pt_regs *regs)
459 if (inb(XD_STATUS) & STAT_INTERRUPT) { /* check if it was our device */
461 printk("xd_interrupt_handler: interrupt detected\n");
462 #endif /* DEBUG_OTHER */
463 outb(0,XD_CONTROL); /* acknowledge interrupt */
464 wake_up(&xd_wait_int); /* and wake up sleeping processes */
468 printk("xd: unexpected interrupt\n");
472 /* xd_setup_dma: set up the DMA controller for a data transfer */
473 static u_char xd_setup_dma (u_char mode,u_char *buffer,u_int count)
479 if (((unsigned long) buffer & 0xFFFF0000) != (((unsigned long) buffer + count) & 0xFFFF0000)) {
481 printk("xd_setup_dma: using PIO, transfer overlaps 64k boundary\n");
482 #endif /* DEBUG_OTHER */
488 clear_dma_ff(xd_dma);
489 set_dma_mode(xd_dma,mode);
490 set_dma_addr(xd_dma, (unsigned long) buffer);
491 set_dma_count(xd_dma,count);
495 return (DMA_MODE); /* use DMA and INT */
498 /* xd_build: put stuff into an array in a format suitable for the controller */
499 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)
502 cmdblk[1] = ((drive & 0x07) << 5) | (head & 0x1F);
503 cmdblk[2] = ((cylinder & 0x300) >> 2) | (sector & 0x3F);
504 cmdblk[3] = cylinder & 0xFF;
511 static void xd_watchdog (unsigned long unused)
514 wake_up(&xd_wait_int);
517 /* xd_waitport: waits until port & mask == flags or a timeout occurs. return 1 for a timeout */
518 static inline u_char xd_waitport (u_short port,u_char flags,u_char mask,u_long timeout)
520 u_long expiry = jiffies + timeout;
524 while ((success = ((inb(port) & mask) != flags)) && time_before(jiffies, expiry)) {
525 set_current_state(TASK_UNINTERRUPTIBLE);
532 static inline u_int xd_wait_for_IRQ (void)
535 xd_watchdog_int.expires = jiffies + 8 * HZ;
536 add_timer(&xd_watchdog_int);
538 flags=claim_dma_lock();
540 release_dma_lock(flags);
542 sleep_on(&xd_wait_int);
543 del_timer(&xd_watchdog_int);
546 flags=claim_dma_lock();
548 release_dma_lock(flags);
551 printk("xd: missed IRQ - command aborted\n");
558 /* xd_command: handle all data transfers necessary for a single command */
559 static u_int xd_command (u_char *command,u_char mode,u_char *indata,u_char *outdata,u_char *sense,u_long timeout)
561 u_char cmdblk[6],csb,complete = 0;
564 printk("xd_command: command = 0x%X, mode = 0x%X, indata = 0x%X, outdata = 0x%X, sense = 0x%X\n",command,mode,indata,outdata,sense);
565 #endif /* DEBUG_COMMAND */
568 outb(mode,XD_CONTROL);
570 if (xd_waitport(XD_STATUS,STAT_SELECT,STAT_SELECT,timeout))
574 if (xd_waitport(XD_STATUS,STAT_READY,STAT_READY,timeout))
577 switch (inb(XD_STATUS) & (STAT_COMMAND | STAT_INPUT)) {
579 if (mode == DMA_MODE) {
580 if (xd_wait_for_IRQ())
583 outb(outdata ? *outdata++ : 0,XD_DATA);
586 if (mode == DMA_MODE) {
587 if (xd_wait_for_IRQ())
591 *indata++ = inb(XD_DATA);
596 outb(command ? *command++ : 0,XD_DATA);
598 case STAT_COMMAND | STAT_INPUT:
605 if (xd_waitport(XD_STATUS,0,STAT_SELECT,timeout)) /* wait until deselected */
608 if (csb & CSB_ERROR) { /* read sense data if error */
609 xd_build(cmdblk,CMD_SENSE,(csb & CSB_LUN) >> 5,0,0,0,0,0);
610 if (xd_command(cmdblk,0,sense,0,0,XD_TIMEOUT))
611 printk("xd: warning! sense command failed!\n");
615 printk("xd_command: completed with csb = 0x%X\n",csb);
616 #endif /* DEBUG_COMMAND */
618 return (csb & CSB_ERROR);
621 static u_char __init xd_initdrives (void (*init_drive)(u_char drive))
623 u_char cmdblk[6],i,count = 0;
625 for (i = 0; i < XD_MAXDRIVES; i++) {
626 xd_build(cmdblk,CMD_TESTREADY,i,0,0,0,0,0);
627 if (!xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 8)) {
628 set_current_state(TASK_INTERRUPTIBLE);
629 schedule_timeout(XD_INIT_DISK_DELAY);
634 set_current_state(TASK_INTERRUPTIBLE);
635 schedule_timeout(XD_INIT_DISK_DELAY);
641 static void __init xd_manual_geo_set (u_char drive)
643 xd_info[drive].heads = (u_char)(xd_geo[3 * drive + 1]);
644 xd_info[drive].cylinders = (u_short)(xd_geo[3 * drive]);
645 xd_info[drive].sectors = (u_char)(xd_geo[3 * drive + 2]);
648 static void __init xd_dtc_init_controller (unsigned int address)
652 case 0xC8000: break; /*initial: 0x320 */
653 case 0xCA000: xd_iobase = 0x324;
654 case 0xD0000: /*5150CX*/
655 case 0xD8000: break; /*5150CX & 5150XL*/
656 default: printk("xd_dtc_init_controller: unsupported BIOS address %06x\n",address);
659 xd_maxsectors = 0x01; /* my card seems to have trouble doing multi-block transfers? */
661 outb(0,XD_RESET); /* reset the controller */
665 static void __init xd_dtc5150cx_init_drive (u_char drive)
667 /* values from controller's BIOS - BIOS chip may be removed */
668 static u_short geometry_table[][4] = {
669 {0x200,8,0x200,0x100},
670 {0x267,2,0x267,0x267},
671 {0x264,4,0x264,0x80},
673 {0x132,2,0x80, 0x132},
677 {0x132,6,0x80, 0x100},
678 {0x200,6,0x100,0x100},
679 {0x264,2,0x264,0x80},
680 {0x280,4,0x280,0x100},
681 {0x2B9,3,0x2B9,0x2B9},
682 {0x2B9,5,0x2B9,0x2B9},
683 {0x280,6,0x280,0x100},
684 {0x132,4,0x132,0x0}};
688 n = (drive ? n : (n >> 2)) & 0x33;
689 n = (n | (n >> 2)) & 0x0F;
691 xd_manual_geo_set(drive);
694 xd_info[drive].heads = (u_char)(geometry_table[n][1]); /* heads */
695 xd_info[drive].cylinders = geometry_table[n][0]; /* cylinders */
696 xd_info[drive].sectors = 17; /* sectors */
698 xd_info[drive].rwrite = geometry_table[n][2]; /* reduced write */
699 xd_info[drive].precomp = geometry_table[n][3] /* write precomp */
700 xd_info[drive].ecc = 0x0B; /* ecc length */
704 printk("xd%c: undetermined drive geometry\n",'a'+drive);
707 xd_info[drive].control = 5; /* control byte */
708 xd_setparam(CMD_DTCSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,geometry_table[n][2],geometry_table[n][3],0x0B);
709 xd_recalibrate(drive);
712 static void __init xd_dtc_init_drive (u_char drive)
714 u_char cmdblk[6],buf[64];
716 xd_build(cmdblk,CMD_DTCGETGEOM,drive,0,0,0,0,0);
717 if (!xd_command(cmdblk,PIO_MODE,buf,0,0,XD_TIMEOUT * 2)) {
718 xd_info[drive].heads = buf[0x0A]; /* heads */
719 xd_info[drive].cylinders = ((u_short *) (buf))[0x04]; /* cylinders */
720 xd_info[drive].sectors = 17; /* sectors */
722 xd_manual_geo_set(drive);
724 xd_info[drive].rwrite = ((u_short *) (buf + 1))[0x05]; /* reduced write */
725 xd_info[drive].precomp = ((u_short *) (buf + 1))[0x06]; /* write precomp */
726 xd_info[drive].ecc = buf[0x0F]; /* ecc length */
728 xd_info[drive].control = 0; /* control byte */
730 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]);
731 xd_build(cmdblk,CMD_DTCSETSTEP,drive,0,0,0,0,7);
732 if (xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 2))
733 printk("xd_dtc_init_drive: error setting step rate for xd%c\n", 'a'+drive);
736 printk("xd_dtc_init_drive: error reading geometry for xd%c\n", 'a'+drive);
739 static void __init xd_wd_init_controller (unsigned int address)
743 case 0xC8000: break; /*initial: 0x320 */
744 case 0xCA000: xd_iobase = 0x324; break;
745 case 0xCC000: xd_iobase = 0x328; break;
746 case 0xCE000: xd_iobase = 0x32C; break;
747 case 0xD0000: xd_iobase = 0x328; break; /* ? */
748 case 0xD8000: xd_iobase = 0x32C; break; /* ? */
749 default: printk("xd_wd_init_controller: unsupported BIOS address %06x\n",address);
752 xd_maxsectors = 0x01; /* this one doesn't wrap properly either... */
754 outb(0,XD_RESET); /* reset the controller */
756 set_current_state(TASK_UNINTERRUPTIBLE);
757 schedule_timeout(XD_INIT_DISK_DELAY);
760 static void __init xd_wd_init_drive (u_char drive)
762 /* values from controller's BIOS - BIOS may be disabled */
763 static u_short geometry_table[][4] = {
764 {0x264,4,0x1C2,0x1C2}, /* common part */
766 {0x267,2,0x1C2,0x1C2},
767 {0x267,4,0x1C2,0x1C2},
769 {0x334,6,0x335,0x335}, /* 1004 series RLL */
770 {0x30E,4,0x30F,0x3DC},
771 {0x30E,2,0x30F,0x30F},
772 {0x267,4,0x268,0x268},
774 {0x3D5,5,0x3D6,0x3D6}, /* 1002 series RLL */
775 {0x3DB,7,0x3DC,0x3DC},
776 {0x264,4,0x265,0x265},
777 {0x267,4,0x268,0x268}};
779 u_char cmdblk[6],buf[0x200];
780 u_char n = 0,rll,jumper_state,use_jumper_geo;
781 u_char wd_1002 = (xd_sigs[xd_type].string[7] == '6');
783 jumper_state = ~(inb(0x322));
784 if (jumper_state & 0x40)
786 rll = (jumper_state & 0x30) ? (0x04 << wd_1002) : 0;
787 xd_build(cmdblk,CMD_READ,drive,0,0,0,1,0);
788 if (!xd_command(cmdblk,PIO_MODE,buf,0,0,XD_TIMEOUT * 2)) {
789 xd_info[drive].heads = buf[0x1AF]; /* heads */
790 xd_info[drive].cylinders = ((u_short *) (buf + 1))[0xD6]; /* cylinders */
791 xd_info[drive].sectors = 17; /* sectors */
793 xd_manual_geo_set(drive);
795 xd_info[drive].rwrite = ((u_short *) (buf))[0xD8]; /* reduced write */
796 xd_info[drive].wprecomp = ((u_short *) (buf))[0xDA]; /* write precomp */
797 xd_info[drive].ecc = buf[0x1B4]; /* ecc length */
799 xd_info[drive].control = buf[0x1B5]; /* control byte */
800 use_jumper_geo = !(xd_info[drive].heads) || !(xd_info[drive].cylinders);
801 if (xd_geo[3*drive]) {
802 xd_manual_geo_set(drive);
803 xd_info[drive].control = rll ? 7 : 5;
805 else if (use_jumper_geo) {
806 n = (((jumper_state & 0x0F) >> (drive << 1)) & 0x03) | rll;
807 xd_info[drive].cylinders = geometry_table[n][0];
808 xd_info[drive].heads = (u_char)(geometry_table[n][1]);
809 xd_info[drive].control = rll ? 7 : 5;
811 xd_info[drive].rwrite = geometry_table[n][2];
812 xd_info[drive].wprecomp = geometry_table[n][3];
813 xd_info[drive].ecc = 0x0B;
818 xd_setparam(CMD_WDSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,
819 geometry_table[n][2],geometry_table[n][3],0x0B);
821 xd_setparam(CMD_WDSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,
822 ((u_short *) (buf))[0xD8],((u_short *) (buf))[0xDA],buf[0x1B4]);
824 /* 1002 based RLL controller requests converted addressing, but reports physical
825 (physical 26 sec., logical 17 sec.)
828 if ((xd_info[drive].cylinders *= 26,
829 xd_info[drive].cylinders /= 17) > 1023)
830 xd_info[drive].cylinders = 1023; /* 1024 ? */
832 xd_info[drive].rwrite *= 26;
833 xd_info[drive].rwrite /= 17;
834 xd_info[drive].wprecomp *= 26
835 xd_info[drive].wprecomp /= 17;
840 printk("xd_wd_init_drive: error reading geometry for xd%c\n",'a'+drive);
844 static void __init xd_seagate_init_controller (unsigned int address)
848 case 0xC8000: break; /*initial: 0x320 */
849 case 0xD0000: xd_iobase = 0x324; break;
850 case 0xD8000: xd_iobase = 0x328; break;
851 case 0xE0000: xd_iobase = 0x32C; break;
852 default: printk("xd_seagate_init_controller: unsupported BIOS address %06x\n",address);
855 xd_maxsectors = 0x40;
857 outb(0,XD_RESET); /* reset the controller */
860 static void __init xd_seagate_init_drive (u_char drive)
862 u_char cmdblk[6],buf[0x200];
864 xd_build(cmdblk,CMD_ST11GETGEOM,drive,0,0,0,1,0);
865 if (!xd_command(cmdblk,PIO_MODE,buf,0,0,XD_TIMEOUT * 2)) {
866 xd_info[drive].heads = buf[0x04]; /* heads */
867 xd_info[drive].cylinders = (buf[0x02] << 8) | buf[0x03]; /* cylinders */
868 xd_info[drive].sectors = buf[0x05]; /* sectors */
869 xd_info[drive].control = 0; /* control byte */
872 printk("xd_seagate_init_drive: error reading geometry from xd%c\n", 'a'+drive);
875 /* Omti support courtesy Dirk Melchers */
876 static void __init xd_omti_init_controller (unsigned int address)
880 case 0xC8000: break; /*initial: 0x320 */
881 case 0xD0000: xd_iobase = 0x324; break;
882 case 0xD8000: xd_iobase = 0x328; break;
883 case 0xE0000: xd_iobase = 0x32C; break;
884 default: printk("xd_omti_init_controller: unsupported BIOS address %06x\n",address);
888 xd_maxsectors = 0x40;
890 outb(0,XD_RESET); /* reset the controller */
893 static void __init xd_omti_init_drive (u_char drive)
895 /* gets infos from drive */
896 xd_override_init_drive(drive);
898 /* set other parameters, Hardcoded, not that nice :-) */
899 xd_info[drive].control = 2;
902 /* Xebec support (AK) */
903 static void __init xd_xebec_init_controller (unsigned int address)
905 /* iobase may be set manually in range 0x300 - 0x33C
906 irq may be set manually to 2(9),3,4,5,6,7
907 dma may be set manually to 1,2,3
908 (How to detect them ???)
909 BIOS address may be set manually in range 0x0 - 0xF8000
910 If you need non-standard settings use the xd=... command */
914 case 0xC8000: /* initially: xd_iobase==0x320 */
924 default: printk("xd_xebec_init_controller: unsupported BIOS address %06x\n",address);
928 xd_maxsectors = 0x01;
929 outb(0,XD_RESET); /* reset the controller */
931 set_current_state(TASK_UNINTERRUPTIBLE);
932 schedule_timeout(XD_INIT_DISK_DELAY);
935 static void __init xd_xebec_init_drive (u_char drive)
937 /* values from controller's BIOS - BIOS chip may be removed */
938 static u_short geometry_table[][5] = {
939 {0x132,4,0x080,0x080,0x7},
940 {0x132,4,0x080,0x080,0x17},
941 {0x264,2,0x100,0x100,0x7},
942 {0x264,2,0x100,0x100,0x17},
943 {0x132,8,0x080,0x080,0x7},
944 {0x132,8,0x080,0x080,0x17},
945 {0x264,4,0x100,0x100,0x6},
946 {0x264,4,0x100,0x100,0x17},
947 {0x2BC,5,0x2BC,0x12C,0x6},
948 {0x3A5,4,0x3A5,0x3A5,0x7},
949 {0x26C,6,0x26C,0x26C,0x7},
950 {0x200,8,0x200,0x100,0x17},
951 {0x400,5,0x400,0x400,0x7},
952 {0x400,6,0x400,0x400,0x7},
953 {0x264,8,0x264,0x200,0x17},
954 {0x33E,7,0x33E,0x200,0x7}};
957 n = inb(XD_JUMPER) & 0x0F; /* BIOS's drive number: same geometry
958 is assumed for BOTH drives */
960 xd_manual_geo_set(drive);
962 xd_info[drive].heads = (u_char)(geometry_table[n][1]); /* heads */
963 xd_info[drive].cylinders = geometry_table[n][0]; /* cylinders */
964 xd_info[drive].sectors = 17; /* sectors */
966 xd_info[drive].rwrite = geometry_table[n][2]; /* reduced write */
967 xd_info[drive].precomp = geometry_table[n][3] /* write precomp */
968 xd_info[drive].ecc = 0x0B; /* ecc length */
971 xd_info[drive].control = geometry_table[n][4]; /* control byte */
972 xd_setparam(CMD_XBSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,geometry_table[n][2],geometry_table[n][3],0x0B);
973 xd_recalibrate(drive);
976 /* xd_override_init_drive: this finds disk geometry in a "binary search" style, narrowing in on the "correct" number of heads
977 etc. by trying values until it gets the highest successful value. Idea courtesy Salvador Abreu (spa@fct.unl.pt). */
978 static void __init xd_override_init_drive (u_char drive)
980 u_short min[] = { 0,0,0 },max[] = { 16,1024,64 },test[] = { 0,0,0 };
984 xd_manual_geo_set(drive);
986 for (i = 0; i < 3; i++) {
987 while (min[i] != max[i] - 1) {
988 test[i] = (min[i] + max[i]) / 2;
989 xd_build(cmdblk,CMD_SEEK,drive,(u_char) test[0],(u_short) test[1],(u_char) test[2],0,0);
990 if (!xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 2))
997 xd_info[drive].heads = (u_char) min[0] + 1;
998 xd_info[drive].cylinders = (u_short) min[1] + 1;
999 xd_info[drive].sectors = (u_char) min[2] + 1;
1001 xd_info[drive].control = 0;
1004 /* xd_setup: initialise controller from command line parameters */
1005 static void __init do_xd_setup (int *integers)
1007 switch (integers[0]) {
1008 case 4: if (integers[4] < 0)
1010 else if (integers[4] < 8)
1011 xd_dma = integers[4];
1012 case 3: if ((integers[3] > 0) && (integers[3] <= 0x3FC))
1013 xd_iobase = integers[3];
1014 case 2: if ((integers[2] > 0) && (integers[2] < 16))
1015 xd_irq = integers[2];
1016 case 1: xd_override = 1;
1017 if ((integers[1] >= 0) && (integers[1] < (sizeof(xd_sigs) / sizeof(xd_sigs[0]))))
1018 xd_type = integers[1];
1020 default:printk("xd: too many parameters for xd\n");
1022 xd_maxsectors = 0x01;
1025 /* xd_setparam: set the drive characteristics */
1026 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)
1030 xd_build(cmdblk,command,drive,0,0,0,0,0);
1031 cmdblk[6] = (u_char) (cylinders >> 8) & 0x03;
1032 cmdblk[7] = (u_char) (cylinders & 0xFF);
1033 cmdblk[8] = heads & 0x1F;
1034 cmdblk[9] = (u_char) (rwrite >> 8) & 0x03;
1035 cmdblk[10] = (u_char) (rwrite & 0xFF);
1036 cmdblk[11] = (u_char) (wprecomp >> 8) & 0x03;
1037 cmdblk[12] = (u_char) (wprecomp & 0xFF);
1040 /* Some controllers require geometry info as data, not command */
1042 if (xd_command(cmdblk,PIO_MODE,0,&cmdblk[6],0,XD_TIMEOUT * 2))
1043 printk("xd: error setting characteristics for xd%c\n", 'a'+drive);
1049 MODULE_PARM(xd, "1-4i");
1050 MODULE_PARM(xd_geo, "3-6i");
1051 MODULE_PARM(nodma, "i");
1053 MODULE_LICENSE("GPL");
1055 void cleanup_module(void)
1058 unregister_blkdev(XT_DISK_MAJOR, "xd");
1059 for (i = 0; i < xd_drives; i++) {
1060 del_gendisk(xd_gendisk[i]);
1061 put_disk(xd_gendisk[i]);
1063 blk_cleanup_queue(xd_queue);
1064 release_region(xd_iobase,4);
1066 free_irq(xd_irq, NULL);
1069 xd_dma_mem_free((unsigned long)xd_dma_buffer, xd_maxsectors * 0x200);
1074 static int __init xd_setup (char *str)
1077 get_options (str, ARRAY_SIZE (ints), ints);
1082 /* xd_manual_geo_init: initialise drive geometry from command line parameters
1083 (used only for WD drives) */
1084 static int __init xd_manual_geo_init (char *str)
1086 int i, integers[1 + 3*XD_MAXDRIVES];
1088 get_options (str, ARRAY_SIZE (integers), integers);
1089 if (integers[0]%3 != 0) {
1090 printk("xd: incorrect number of parameters for xd_geo\n");
1093 for (i = 0; (i < integers[0]) && (i < 3*XD_MAXDRIVES); i++)
1094 xd_geo[i] = integers[i+1];
1098 __setup ("xd=", xd_setup);
1099 __setup ("xd_geo=", xd_manual_geo_init);
1103 module_init(xd_init);
1104 MODULE_ALIAS_BLOCKDEV_MAJOR(XT_DISK_MAJOR);