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/mutex.h>
50 #include <linux/blkpg.h>
51 #include <linux/delay.h>
53 #include <linux/gfp.h>
55 #include <asm/system.h>
56 #include <asm/uaccess.h>
61 static DEFINE_MUTEX(xd_mutex
);
62 static void __init
do_xd_setup (int *integers
);
64 static int xd
[5] = { -1,-1,-1,-1, };
67 #define XD_DONT_USE_DMA 0 /* Initial value. may be overriden using
68 "nodma" module option */
69 #define XD_INIT_DISK_DELAY (30) /* 30 ms delay during disk initialization */
71 /* Above may need to be increased if a problem with the 2nd drive detection
72 (ST11M controller) or resetting a controller (WD) appears */
74 static XD_INFO xd_info
[XD_MAXDRIVES
];
76 /* If you try this driver and find that your card is not detected by the driver at bootup, you need to add your BIOS
77 signature and details to the following list of signatures. A BIOS signature is a string embedded into the first
78 few bytes of your controller's on-board ROM BIOS. To find out what yours is, use something like MS-DOS's DEBUG
79 command. Run DEBUG, and then you can examine your BIOS signature with:
83 where xxxx is the segment of your controller (like C800 or D000 or something). On the ASCII dump at the right, you should
84 be able to see a string mentioning the manufacturer's copyright etc. Add this string into the table below. The parameters
85 in the table are, in order:
87 offset ; this is the offset (in bytes) from the start of your ROM where the signature starts
88 signature ; this is the actual text of the signature
89 xd_?_init_controller ; this is the controller init routine used by your controller
90 xd_?_init_drive ; this is the drive init routine used by your controller
92 The controllers directly supported at the moment are: DTC 5150x, WD 1004A27X, ST11M/R and override. If your controller is
93 made by the same manufacturer as one of these, try using the same init routines as they do. If that doesn't work, your
94 best bet is to use the "override" routines. These routines use a "portable" method of getting the disk's geometry, and
95 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>.
97 NOTE: You can now specify your XT controller's parameters from the command line in the form xd=TYPE,IRQ,IO,DMA. The driver
98 should be able to detect your drive's geometry from this info. (eg: xd=0,5,0x320,3 is the "standard"). */
100 #include <asm/page.h>
101 #define xd_dma_mem_alloc(size) __get_dma_pages(GFP_KERNEL,get_order(size))
102 #define xd_dma_mem_free(addr, size) free_pages(addr, get_order(size))
103 static char *xd_dma_buffer
;
105 static XD_SIGNATURE xd_sigs
[] __initdata
= {
106 { 0x0000,"Override geometry handler",NULL
,xd_override_init_drive
,"n unknown" }, /* Pat Mackinlay, pat@it.com.au */
107 { 0x0008,"[BXD06 (C) DTC 17-MAY-1985]",xd_dtc_init_controller
,xd_dtc5150cx_init_drive
," DTC 5150CX" }, /* Andrzej Krzysztofowicz, ankry@mif.pg.gda.pl */
108 { 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 */
109 { 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 */
110 { 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 */
111 { 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 */
112 { 0x0015,"SEAGATE ST11 BIOS REVISION",xd_seagate_init_controller
,xd_seagate_init_drive
," Seagate ST11M/R" }, /* Salvador Abreu, spa@fct.unl.pt */
113 { 0x0010,"ST11R BIOS",xd_seagate_init_controller
,xd_seagate_init_drive
," Seagate ST11M/R" }, /* Risto Kankkunen, risto.kankkunen@cs.helsinki.fi */
114 { 0x0010,"ST11 BIOS v1.7",xd_seagate_init_controller
,xd_seagate_init_drive
," Seagate ST11R" }, /* Alan Hourihane, alanh@fairlite.demon.co.uk */
115 { 0x1000,"(c)Copyright 1987 SMS",xd_omti_init_controller
,xd_omti_init_drive
,"n OMTI 5520" }, /* Dirk Melchers, dirk@merlin.nbg.sub.org */
116 { 0x0006,"COPYRIGHT XEBEC (C) 1984",xd_xebec_init_controller
,xd_xebec_init_drive
," XEBEC" }, /* Andrzej Krzysztofowicz, ankry@mif.pg.gda.pl */
117 { 0x0008,"(C) Copyright 1984 Western Digital Corp", xd_wd_init_controller
, xd_wd_init_drive
," Western Dig. 1002s-wx2" },
118 { 0x0008,"(C) Copyright 1986 Western Digital Corporation", xd_wd_init_controller
, xd_wd_init_drive
," 1986 Western Digital" }, /* jfree@sovereign.org */
121 static unsigned int xd_bases
[] __initdata
=
123 0xC8000, 0xCA000, 0xCC000,
124 0xCE000, 0xD0000, 0xD2000,
125 0xD4000, 0xD6000, 0xD8000,
126 0xDA000, 0xDC000, 0xDE000,
130 static DEFINE_SPINLOCK(xd_lock
);
132 static struct gendisk
*xd_gendisk
[2];
134 static int xd_getgeo(struct block_device
*bdev
, struct hd_geometry
*geo
);
136 static const struct block_device_operations xd_fops
= {
137 .owner
= THIS_MODULE
,
141 static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int
);
142 static u_char xd_drives
, xd_irq
= 5, xd_dma
= 3, xd_maxsectors
;
143 static u_char xd_override __initdata
= 0, xd_type __initdata
= 0;
144 static u_short xd_iobase
= 0x320;
145 static int xd_geo
[XD_MAXDRIVES
*3] __initdata
= { 0, };
147 static volatile int xdc_busy
;
148 static struct timer_list xd_watchdog_int
;
150 static volatile u_char xd_error
;
151 static int nodma
= XD_DONT_USE_DMA
;
153 static struct request_queue
*xd_queue
;
155 /* xd_init: register the block device number and set up pointer tables */
156 static int __init
xd_init(void)
159 unsigned int address
;
165 for (i
= 4; i
> 0; i
--)
166 if (((xd
[i
] = xd
[i
-1]) >= 0) && !count
)
173 init_timer (&xd_watchdog_int
); xd_watchdog_int
.function
= xd_watchdog
;
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
);
202 * With the drive detected, xd_maxsectors should now be known.
203 * If xd_maxsectors is 0, nothing was detected and we fall through
206 if (!xd_dma_buffer
&& xd_maxsectors
) {
207 xd_dma_buffer
= (char *)xd_dma_mem_alloc(xd_maxsectors
* 0x200);
208 if (!xd_dma_buffer
) {
209 printk(KERN_ERR
"xd: Out of memory.\n");
218 for (i
= 0; i
< xd_drives
; i
++) {
219 XD_INFO
*p
= &xd_info
[i
];
220 struct gendisk
*disk
= alloc_disk(64);
224 disk
->major
= XT_DISK_MAJOR
;
225 disk
->first_minor
= i
<<6;
226 sprintf(disk
->disk_name
, "xd%c", i
+'a');
227 disk
->fops
= &xd_fops
;
228 disk
->private_data
= p
;
229 disk
->queue
= xd_queue
;
230 set_capacity(disk
, p
->heads
* p
->cylinders
* p
->sectors
);
231 printk(" %s: CHS=%d/%d/%d\n", disk
->disk_name
,
232 p
->cylinders
, p
->heads
, p
->sectors
);
233 xd_gendisk
[i
] = disk
;
237 if (request_irq(xd_irq
,xd_interrupt_handler
, 0, "XT hard disk", NULL
)) {
238 printk("xd: unable to get IRQ%d\n",xd_irq
);
242 if (request_dma(xd_dma
,"xd")) {
243 printk("xd: unable to get DMA%d\n",xd_dma
);
247 /* xd_maxsectors depends on controller - so set after detection */
248 blk_queue_max_hw_sectors(xd_queue
, xd_maxsectors
);
250 for (i
= 0; i
< xd_drives
; i
++)
251 add_disk(xd_gendisk
[i
]);
256 free_irq(xd_irq
, NULL
);
258 for (i
= 0; i
< xd_drives
; i
++)
259 put_disk(xd_gendisk
[i
]);
262 release_region(xd_iobase
,4);
265 xd_dma_mem_free((unsigned long)xd_dma_buffer
,
266 xd_maxsectors
* 0x200);
268 blk_cleanup_queue(xd_queue
);
270 unregister_blkdev(XT_DISK_MAJOR
, "xd");
276 put_disk(xd_gendisk
[i
]);
280 /* xd_detect: scan the possible BIOS ROM locations for the signature strings */
281 static u_char __init
xd_detect (u_char
*controller
, unsigned int *address
)
287 *controller
= xd_type
;
292 for (i
= 0; i
< ARRAY_SIZE(xd_bases
); i
++) {
293 void __iomem
*p
= ioremap(xd_bases
[i
], 0x2000);
296 for (j
= 1; j
< ARRAY_SIZE(xd_sigs
); j
++) {
297 const char *s
= xd_sigs
[j
].string
;
298 if (check_signature(p
+ xd_sigs
[j
].offset
, s
, strlen(s
))) {
301 *address
= xd_bases
[i
];
311 /* do_xd_request: handle an incoming request */
312 static void do_xd_request (struct request_queue
* q
)
319 req
= blk_fetch_request(q
);
321 unsigned block
= blk_rq_pos(req
);
322 unsigned count
= blk_rq_cur_sectors(req
);
323 XD_INFO
*disk
= req
->rq_disk
->private_data
;
327 if (req
->cmd_type
!= REQ_TYPE_FS
)
329 if (block
+ count
> get_capacity(req
->rq_disk
))
331 for (retry
= 0; (retry
< XD_RETRIES
) && !res
; retry
++)
332 res
= xd_readwrite(rq_data_dir(req
), disk
, req
->buffer
,
335 /* wrap up, 0 = success, -errno = fail */
336 if (!__blk_end_request_cur(req
, res
))
337 req
= blk_fetch_request(q
);
341 static int xd_getgeo(struct block_device
*bdev
, struct hd_geometry
*geo
)
343 XD_INFO
*p
= bdev
->bd_disk
->private_data
;
345 geo
->heads
= p
->heads
;
346 geo
->sectors
= p
->sectors
;
347 geo
->cylinders
= p
->cylinders
;
351 /* xd_ioctl: handle device ioctl's */
352 static int xd_locked_ioctl(struct block_device
*bdev
, fmode_t mode
, u_int cmd
, u_long arg
)
356 if (!capable(CAP_SYS_ADMIN
)) return -EACCES
;
357 if (xdc_busy
) return -EBUSY
;
359 if (nodma
&& xd_dma_buffer
) {
360 xd_dma_mem_free((unsigned long)xd_dma_buffer
,
361 xd_maxsectors
* 0x200);
362 xd_dma_buffer
= NULL
;
363 } else if (!nodma
&& !xd_dma_buffer
) {
364 xd_dma_buffer
= (char *)xd_dma_mem_alloc(xd_maxsectors
* 0x200);
365 if (!xd_dma_buffer
) {
366 nodma
= XD_DONT_USE_DMA
;
372 return put_user(!nodma
, (long __user
*) arg
);
373 case HDIO_GET_MULTCOUNT
:
374 return put_user(xd_maxsectors
, (long __user
*) arg
);
380 static int xd_ioctl(struct block_device
*bdev
, fmode_t mode
,
381 unsigned int cmd
, unsigned long param
)
385 mutex_lock(&xd_mutex
);
386 ret
= xd_locked_ioctl(bdev
, mode
, cmd
, param
);
387 mutex_unlock(&xd_mutex
);
392 /* xd_readwrite: handle a read/write request */
393 static int xd_readwrite (u_char operation
,XD_INFO
*p
,char *buffer
,u_int block
,u_int count
)
396 u_char cmdblk
[6],sense
[4];
397 u_short track
,cylinder
;
398 u_char head
,sector
,control
,mode
= PIO_MODE
,temp
;
402 #ifdef DEBUG_READWRITE
403 printk("xd_readwrite: operation = %s, drive = %d, buffer = 0x%X, block = %d, count = %d\n",operation
== READ
? "read" : "write",drive
,buffer
,block
,count
);
404 #endif /* DEBUG_READWRITE */
406 spin_unlock_irq(&xd_lock
);
408 control
= p
->control
;
410 xd_dma_buffer
= (char *)xd_dma_mem_alloc(xd_maxsectors
* 0x200);
412 temp
= count
< xd_maxsectors
? count
: xd_maxsectors
;
414 track
= block
/ p
->sectors
;
415 head
= track
% p
->heads
;
416 cylinder
= track
/ p
->heads
;
417 sector
= block
% p
->sectors
;
419 #ifdef DEBUG_READWRITE
420 printk("xd_readwrite: drive = %d, head = %d, cylinder = %d, sector = %d, count = %d\n",drive
,head
,cylinder
,sector
,temp
);
421 #endif /* DEBUG_READWRITE */
424 mode
= xd_setup_dma(operation
== READ
? DMA_MODE_READ
: DMA_MODE_WRITE
,(u_char
*)(xd_dma_buffer
),temp
* 0x200);
425 real_buffer
= &xd_dma_buffer
;
426 for (i
=0; i
< (temp
* 0x200); i
++)
427 xd_dma_buffer
[i
] = buffer
[i
];
430 real_buffer
= &buffer
;
432 xd_build(cmdblk
,operation
== READ
? CMD_READ
: CMD_WRITE
,drive
,head
,cylinder
,sector
,temp
& 0xFF,control
);
434 switch (xd_command(cmdblk
,mode
,(u_char
*)(*real_buffer
),(u_char
*)(*real_buffer
),sense
,XD_TIMEOUT
)) {
436 printk("xd%c: %s timeout, recalibrating drive\n",'a'+drive
,(operation
== READ
? "read" : "write"));
437 xd_recalibrate(drive
);
438 spin_lock_irq(&xd_lock
);
441 if (sense
[0] & 0x30) {
442 printk("xd%c: %s - ",'a'+drive
,(operation
== READ
? "reading" : "writing"));
443 switch ((sense
[0] & 0x30) >> 4) {
444 case 0: printk("drive error, code = 0x%X",sense
[0] & 0x0F);
446 case 1: printk("controller error, code = 0x%X",sense
[0] & 0x0F);
448 case 2: printk("command error, code = 0x%X",sense
[0] & 0x0F);
450 case 3: printk("miscellaneous error, code = 0x%X",sense
[0] & 0x0F);
455 printk(" - CHS = %d/%d/%d\n",((sense
[2] & 0xC0) << 2) | sense
[3],sense
[1] & 0x1F,sense
[2] & 0x3F);
456 /* reported drive number = (sense[1] & 0xE0) >> 5 */
458 printk(" - no valid disk address\n");
459 spin_lock_irq(&xd_lock
);
463 for (i
=0; i
< (temp
* 0x200); i
++)
464 buffer
[i
] = xd_dma_buffer
[i
];
466 count
-= temp
, buffer
+= temp
* 0x200, block
+= temp
;
468 spin_lock_irq(&xd_lock
);
472 /* xd_recalibrate: recalibrate a given drive and reset controller if necessary */
473 static void xd_recalibrate (u_char drive
)
477 xd_build(cmdblk
,CMD_RECALIBRATE
,drive
,0,0,0,0,0);
478 if (xd_command(cmdblk
,PIO_MODE
,NULL
,NULL
,NULL
,XD_TIMEOUT
* 8))
479 printk("xd%c: warning! error recalibrating, controller may be unstable\n", 'a'+drive
);
482 /* xd_interrupt_handler: interrupt service routine */
483 static irqreturn_t
xd_interrupt_handler(int irq
, void *dev_id
)
485 if (inb(XD_STATUS
) & STAT_INTERRUPT
) { /* check if it was our device */
487 printk("xd_interrupt_handler: interrupt detected\n");
488 #endif /* DEBUG_OTHER */
489 outb(0,XD_CONTROL
); /* acknowledge interrupt */
490 wake_up(&xd_wait_int
); /* and wake up sleeping processes */
494 printk("xd: unexpected interrupt\n");
498 /* xd_setup_dma: set up the DMA controller for a data transfer */
499 static u_char
xd_setup_dma (u_char mode
,u_char
*buffer
,u_int count
)
505 if (((unsigned long) buffer
& 0xFFFF0000) != (((unsigned long) buffer
+ count
) & 0xFFFF0000)) {
507 printk("xd_setup_dma: using PIO, transfer overlaps 64k boundary\n");
508 #endif /* DEBUG_OTHER */
514 clear_dma_ff(xd_dma
);
515 set_dma_mode(xd_dma
,mode
);
516 set_dma_addr(xd_dma
, (unsigned long) buffer
);
517 set_dma_count(xd_dma
,count
);
521 return (DMA_MODE
); /* use DMA and INT */
524 /* xd_build: put stuff into an array in a format suitable for the controller */
525 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
)
528 cmdblk
[1] = ((drive
& 0x07) << 5) | (head
& 0x1F);
529 cmdblk
[2] = ((cylinder
& 0x300) >> 2) | (sector
& 0x3F);
530 cmdblk
[3] = cylinder
& 0xFF;
537 static void xd_watchdog (unsigned long unused
)
540 wake_up(&xd_wait_int
);
543 /* xd_waitport: waits until port & mask == flags or a timeout occurs. return 1 for a timeout */
544 static inline u_char
xd_waitport (u_short port
,u_char flags
,u_char mask
,u_long timeout
)
546 u_long expiry
= jiffies
+ timeout
;
550 while ((success
= ((inb(port
) & mask
) != flags
)) && time_before(jiffies
, expiry
))
551 schedule_timeout_uninterruptible(1);
556 static inline u_int
xd_wait_for_IRQ (void)
559 xd_watchdog_int
.expires
= jiffies
+ 8 * HZ
;
560 add_timer(&xd_watchdog_int
);
562 flags
=claim_dma_lock();
564 release_dma_lock(flags
);
566 sleep_on(&xd_wait_int
);
567 del_timer(&xd_watchdog_int
);
570 flags
=claim_dma_lock();
572 release_dma_lock(flags
);
575 printk("xd: missed IRQ - command aborted\n");
582 /* xd_command: handle all data transfers necessary for a single command */
583 static u_int
xd_command (u_char
*command
,u_char mode
,u_char
*indata
,u_char
*outdata
,u_char
*sense
,u_long timeout
)
585 u_char cmdblk
[6],csb
,complete
= 0;
588 printk("xd_command: command = 0x%X, mode = 0x%X, indata = 0x%X, outdata = 0x%X, sense = 0x%X\n",command
,mode
,indata
,outdata
,sense
);
589 #endif /* DEBUG_COMMAND */
592 outb(mode
,XD_CONTROL
);
594 if (xd_waitport(XD_STATUS
,STAT_SELECT
,STAT_SELECT
,timeout
))
598 if (xd_waitport(XD_STATUS
,STAT_READY
,STAT_READY
,timeout
))
601 switch (inb(XD_STATUS
) & (STAT_COMMAND
| STAT_INPUT
)) {
603 if (mode
== DMA_MODE
) {
604 if (xd_wait_for_IRQ())
607 outb(outdata
? *outdata
++ : 0,XD_DATA
);
610 if (mode
== DMA_MODE
) {
611 if (xd_wait_for_IRQ())
615 *indata
++ = inb(XD_DATA
);
620 outb(command
? *command
++ : 0,XD_DATA
);
622 case STAT_COMMAND
| STAT_INPUT
:
629 if (xd_waitport(XD_STATUS
,0,STAT_SELECT
,timeout
)) /* wait until deselected */
632 if (csb
& CSB_ERROR
) { /* read sense data if error */
633 xd_build(cmdblk
,CMD_SENSE
,(csb
& CSB_LUN
) >> 5,0,0,0,0,0);
634 if (xd_command(cmdblk
,0,sense
,NULL
,NULL
,XD_TIMEOUT
))
635 printk("xd: warning! sense command failed!\n");
639 printk("xd_command: completed with csb = 0x%X\n",csb
);
640 #endif /* DEBUG_COMMAND */
642 return (csb
& CSB_ERROR
);
645 static u_char __init
xd_initdrives (void (*init_drive
)(u_char drive
))
647 u_char cmdblk
[6],i
,count
= 0;
649 for (i
= 0; i
< XD_MAXDRIVES
; i
++) {
650 xd_build(cmdblk
,CMD_TESTREADY
,i
,0,0,0,0,0);
651 if (!xd_command(cmdblk
,PIO_MODE
,NULL
,NULL
,NULL
,XD_TIMEOUT
*8)) {
652 msleep_interruptible(XD_INIT_DISK_DELAY
);
657 msleep_interruptible(XD_INIT_DISK_DELAY
);
663 static void __init
xd_manual_geo_set (u_char drive
)
665 xd_info
[drive
].heads
= (u_char
)(xd_geo
[3 * drive
+ 1]);
666 xd_info
[drive
].cylinders
= (u_short
)(xd_geo
[3 * drive
]);
667 xd_info
[drive
].sectors
= (u_char
)(xd_geo
[3 * drive
+ 2]);
670 static void __init
xd_dtc_init_controller (unsigned int address
)
674 case 0xC8000: break; /*initial: 0x320 */
675 case 0xCA000: xd_iobase
= 0x324;
676 case 0xD0000: /*5150CX*/
677 case 0xD8000: break; /*5150CX & 5150XL*/
678 default: printk("xd_dtc_init_controller: unsupported BIOS address %06x\n",address
);
681 xd_maxsectors
= 0x01; /* my card seems to have trouble doing multi-block transfers? */
683 outb(0,XD_RESET
); /* reset the controller */
687 static void __init
xd_dtc5150cx_init_drive (u_char drive
)
689 /* values from controller's BIOS - BIOS chip may be removed */
690 static u_short geometry_table
[][4] = {
691 {0x200,8,0x200,0x100},
692 {0x267,2,0x267,0x267},
693 {0x264,4,0x264,0x80},
695 {0x132,2,0x80, 0x132},
699 {0x132,6,0x80, 0x100},
700 {0x200,6,0x100,0x100},
701 {0x264,2,0x264,0x80},
702 {0x280,4,0x280,0x100},
703 {0x2B9,3,0x2B9,0x2B9},
704 {0x2B9,5,0x2B9,0x2B9},
705 {0x280,6,0x280,0x100},
706 {0x132,4,0x132,0x0}};
710 n
= (drive
? n
: (n
>> 2)) & 0x33;
711 n
= (n
| (n
>> 2)) & 0x0F;
713 xd_manual_geo_set(drive
);
716 xd_info
[drive
].heads
= (u_char
)(geometry_table
[n
][1]); /* heads */
717 xd_info
[drive
].cylinders
= geometry_table
[n
][0]; /* cylinders */
718 xd_info
[drive
].sectors
= 17; /* sectors */
720 xd_info
[drive
].rwrite
= geometry_table
[n
][2]; /* reduced write */
721 xd_info
[drive
].precomp
= geometry_table
[n
][3] /* write precomp */
722 xd_info
[drive
].ecc
= 0x0B; /* ecc length */
726 printk("xd%c: undetermined drive geometry\n",'a'+drive
);
729 xd_info
[drive
].control
= 5; /* control byte */
730 xd_setparam(CMD_DTCSETPARAM
,drive
,xd_info
[drive
].heads
,xd_info
[drive
].cylinders
,geometry_table
[n
][2],geometry_table
[n
][3],0x0B);
731 xd_recalibrate(drive
);
734 static void __init
xd_dtc_init_drive (u_char drive
)
736 u_char cmdblk
[6],buf
[64];
738 xd_build(cmdblk
,CMD_DTCGETGEOM
,drive
,0,0,0,0,0);
739 if (!xd_command(cmdblk
,PIO_MODE
,buf
,NULL
,NULL
,XD_TIMEOUT
* 2)) {
740 xd_info
[drive
].heads
= buf
[0x0A]; /* heads */
741 xd_info
[drive
].cylinders
= ((u_short
*) (buf
))[0x04]; /* cylinders */
742 xd_info
[drive
].sectors
= 17; /* sectors */
744 xd_manual_geo_set(drive
);
746 xd_info
[drive
].rwrite
= ((u_short
*) (buf
+ 1))[0x05]; /* reduced write */
747 xd_info
[drive
].precomp
= ((u_short
*) (buf
+ 1))[0x06]; /* write precomp */
748 xd_info
[drive
].ecc
= buf
[0x0F]; /* ecc length */
750 xd_info
[drive
].control
= 0; /* control byte */
752 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]);
753 xd_build(cmdblk
,CMD_DTCSETSTEP
,drive
,0,0,0,0,7);
754 if (xd_command(cmdblk
,PIO_MODE
,NULL
,NULL
,NULL
,XD_TIMEOUT
* 2))
755 printk("xd_dtc_init_drive: error setting step rate for xd%c\n", 'a'+drive
);
758 printk("xd_dtc_init_drive: error reading geometry for xd%c\n", 'a'+drive
);
761 static void __init
xd_wd_init_controller (unsigned int address
)
765 case 0xC8000: break; /*initial: 0x320 */
766 case 0xCA000: xd_iobase
= 0x324; break;
767 case 0xCC000: xd_iobase
= 0x328; break;
768 case 0xCE000: xd_iobase
= 0x32C; break;
769 case 0xD0000: xd_iobase
= 0x328; break; /* ? */
770 case 0xD8000: xd_iobase
= 0x32C; break; /* ? */
771 default: printk("xd_wd_init_controller: unsupported BIOS address %06x\n",address
);
774 xd_maxsectors
= 0x01; /* this one doesn't wrap properly either... */
776 outb(0,XD_RESET
); /* reset the controller */
778 msleep(XD_INIT_DISK_DELAY
);
781 static void __init
xd_wd_init_drive (u_char drive
)
783 /* values from controller's BIOS - BIOS may be disabled */
784 static u_short geometry_table
[][4] = {
785 {0x264,4,0x1C2,0x1C2}, /* common part */
787 {0x267,2,0x1C2,0x1C2},
788 {0x267,4,0x1C2,0x1C2},
790 {0x334,6,0x335,0x335}, /* 1004 series RLL */
791 {0x30E,4,0x30F,0x3DC},
792 {0x30E,2,0x30F,0x30F},
793 {0x267,4,0x268,0x268},
795 {0x3D5,5,0x3D6,0x3D6}, /* 1002 series RLL */
796 {0x3DB,7,0x3DC,0x3DC},
797 {0x264,4,0x265,0x265},
798 {0x267,4,0x268,0x268}};
800 u_char cmdblk
[6],buf
[0x200];
801 u_char n
= 0,rll
,jumper_state
,use_jumper_geo
;
802 u_char wd_1002
= (xd_sigs
[xd_type
].string
[7] == '6');
804 jumper_state
= ~(inb(0x322));
805 if (jumper_state
& 0x40)
807 rll
= (jumper_state
& 0x30) ? (0x04 << wd_1002
) : 0;
808 xd_build(cmdblk
,CMD_READ
,drive
,0,0,0,1,0);
809 if (!xd_command(cmdblk
,PIO_MODE
,buf
,NULL
,NULL
,XD_TIMEOUT
* 2)) {
810 xd_info
[drive
].heads
= buf
[0x1AF]; /* heads */
811 xd_info
[drive
].cylinders
= ((u_short
*) (buf
+ 1))[0xD6]; /* cylinders */
812 xd_info
[drive
].sectors
= 17; /* sectors */
814 xd_manual_geo_set(drive
);
816 xd_info
[drive
].rwrite
= ((u_short
*) (buf
))[0xD8]; /* reduced write */
817 xd_info
[drive
].wprecomp
= ((u_short
*) (buf
))[0xDA]; /* write precomp */
818 xd_info
[drive
].ecc
= buf
[0x1B4]; /* ecc length */
820 xd_info
[drive
].control
= buf
[0x1B5]; /* control byte */
821 use_jumper_geo
= !(xd_info
[drive
].heads
) || !(xd_info
[drive
].cylinders
);
822 if (xd_geo
[3*drive
]) {
823 xd_manual_geo_set(drive
);
824 xd_info
[drive
].control
= rll
? 7 : 5;
826 else if (use_jumper_geo
) {
827 n
= (((jumper_state
& 0x0F) >> (drive
<< 1)) & 0x03) | rll
;
828 xd_info
[drive
].cylinders
= geometry_table
[n
][0];
829 xd_info
[drive
].heads
= (u_char
)(geometry_table
[n
][1]);
830 xd_info
[drive
].control
= rll
? 7 : 5;
832 xd_info
[drive
].rwrite
= geometry_table
[n
][2];
833 xd_info
[drive
].wprecomp
= geometry_table
[n
][3];
834 xd_info
[drive
].ecc
= 0x0B;
839 xd_setparam(CMD_WDSETPARAM
,drive
,xd_info
[drive
].heads
,xd_info
[drive
].cylinders
,
840 geometry_table
[n
][2],geometry_table
[n
][3],0x0B);
842 xd_setparam(CMD_WDSETPARAM
,drive
,xd_info
[drive
].heads
,xd_info
[drive
].cylinders
,
843 ((u_short
*) (buf
))[0xD8],((u_short
*) (buf
))[0xDA],buf
[0x1B4]);
845 /* 1002 based RLL controller requests converted addressing, but reports physical
846 (physical 26 sec., logical 17 sec.)
849 if ((xd_info
[drive
].cylinders
*= 26,
850 xd_info
[drive
].cylinders
/= 17) > 1023)
851 xd_info
[drive
].cylinders
= 1023; /* 1024 ? */
853 xd_info
[drive
].rwrite
*= 26;
854 xd_info
[drive
].rwrite
/= 17;
855 xd_info
[drive
].wprecomp
*= 26
856 xd_info
[drive
].wprecomp
/= 17;
861 printk("xd_wd_init_drive: error reading geometry for xd%c\n",'a'+drive
);
865 static void __init
xd_seagate_init_controller (unsigned int address
)
869 case 0xC8000: break; /*initial: 0x320 */
870 case 0xD0000: xd_iobase
= 0x324; break;
871 case 0xD8000: xd_iobase
= 0x328; break;
872 case 0xE0000: xd_iobase
= 0x32C; break;
873 default: printk("xd_seagate_init_controller: unsupported BIOS address %06x\n",address
);
876 xd_maxsectors
= 0x40;
878 outb(0,XD_RESET
); /* reset the controller */
881 static void __init
xd_seagate_init_drive (u_char drive
)
883 u_char cmdblk
[6],buf
[0x200];
885 xd_build(cmdblk
,CMD_ST11GETGEOM
,drive
,0,0,0,1,0);
886 if (!xd_command(cmdblk
,PIO_MODE
,buf
,NULL
,NULL
,XD_TIMEOUT
* 2)) {
887 xd_info
[drive
].heads
= buf
[0x04]; /* heads */
888 xd_info
[drive
].cylinders
= (buf
[0x02] << 8) | buf
[0x03]; /* cylinders */
889 xd_info
[drive
].sectors
= buf
[0x05]; /* sectors */
890 xd_info
[drive
].control
= 0; /* control byte */
893 printk("xd_seagate_init_drive: error reading geometry from xd%c\n", 'a'+drive
);
896 /* Omti support courtesy Dirk Melchers */
897 static void __init
xd_omti_init_controller (unsigned int address
)
901 case 0xC8000: break; /*initial: 0x320 */
902 case 0xD0000: xd_iobase
= 0x324; break;
903 case 0xD8000: xd_iobase
= 0x328; break;
904 case 0xE0000: xd_iobase
= 0x32C; break;
905 default: printk("xd_omti_init_controller: unsupported BIOS address %06x\n",address
);
909 xd_maxsectors
= 0x40;
911 outb(0,XD_RESET
); /* reset the controller */
914 static void __init
xd_omti_init_drive (u_char drive
)
916 /* gets infos from drive */
917 xd_override_init_drive(drive
);
919 /* set other parameters, Hardcoded, not that nice :-) */
920 xd_info
[drive
].control
= 2;
923 /* Xebec support (AK) */
924 static void __init
xd_xebec_init_controller (unsigned int address
)
926 /* iobase may be set manually in range 0x300 - 0x33C
927 irq may be set manually to 2(9),3,4,5,6,7
928 dma may be set manually to 1,2,3
929 (How to detect them ???)
930 BIOS address may be set manually in range 0x0 - 0xF8000
931 If you need non-standard settings use the xd=... command */
935 case 0xC8000: /* initially: xd_iobase==0x320 */
945 default: printk("xd_xebec_init_controller: unsupported BIOS address %06x\n",address
);
949 xd_maxsectors
= 0x01;
950 outb(0,XD_RESET
); /* reset the controller */
952 msleep(XD_INIT_DISK_DELAY
);
955 static void __init
xd_xebec_init_drive (u_char drive
)
957 /* values from controller's BIOS - BIOS chip may be removed */
958 static u_short geometry_table
[][5] = {
959 {0x132,4,0x080,0x080,0x7},
960 {0x132,4,0x080,0x080,0x17},
961 {0x264,2,0x100,0x100,0x7},
962 {0x264,2,0x100,0x100,0x17},
963 {0x132,8,0x080,0x080,0x7},
964 {0x132,8,0x080,0x080,0x17},
965 {0x264,4,0x100,0x100,0x6},
966 {0x264,4,0x100,0x100,0x17},
967 {0x2BC,5,0x2BC,0x12C,0x6},
968 {0x3A5,4,0x3A5,0x3A5,0x7},
969 {0x26C,6,0x26C,0x26C,0x7},
970 {0x200,8,0x200,0x100,0x17},
971 {0x400,5,0x400,0x400,0x7},
972 {0x400,6,0x400,0x400,0x7},
973 {0x264,8,0x264,0x200,0x17},
974 {0x33E,7,0x33E,0x200,0x7}};
977 n
= inb(XD_JUMPER
) & 0x0F; /* BIOS's drive number: same geometry
978 is assumed for BOTH drives */
980 xd_manual_geo_set(drive
);
982 xd_info
[drive
].heads
= (u_char
)(geometry_table
[n
][1]); /* heads */
983 xd_info
[drive
].cylinders
= geometry_table
[n
][0]; /* cylinders */
984 xd_info
[drive
].sectors
= 17; /* sectors */
986 xd_info
[drive
].rwrite
= geometry_table
[n
][2]; /* reduced write */
987 xd_info
[drive
].precomp
= geometry_table
[n
][3] /* write precomp */
988 xd_info
[drive
].ecc
= 0x0B; /* ecc length */
991 xd_info
[drive
].control
= geometry_table
[n
][4]; /* control byte */
992 xd_setparam(CMD_XBSETPARAM
,drive
,xd_info
[drive
].heads
,xd_info
[drive
].cylinders
,geometry_table
[n
][2],geometry_table
[n
][3],0x0B);
993 xd_recalibrate(drive
);
996 /* xd_override_init_drive: this finds disk geometry in a "binary search" style, narrowing in on the "correct" number of heads
997 etc. by trying values until it gets the highest successful value. Idea courtesy Salvador Abreu (spa@fct.unl.pt). */
998 static void __init
xd_override_init_drive (u_char drive
)
1000 u_short min
[] = { 0,0,0 },max
[] = { 16,1024,64 },test
[] = { 0,0,0 };
1003 if (xd_geo
[3*drive
])
1004 xd_manual_geo_set(drive
);
1006 for (i
= 0; i
< 3; i
++) {
1007 while (min
[i
] != max
[i
] - 1) {
1008 test
[i
] = (min
[i
] + max
[i
]) / 2;
1009 xd_build(cmdblk
,CMD_SEEK
,drive
,(u_char
) test
[0],(u_short
) test
[1],(u_char
) test
[2],0,0);
1010 if (!xd_command(cmdblk
,PIO_MODE
,NULL
,NULL
,NULL
,XD_TIMEOUT
* 2))
1017 xd_info
[drive
].heads
= (u_char
) min
[0] + 1;
1018 xd_info
[drive
].cylinders
= (u_short
) min
[1] + 1;
1019 xd_info
[drive
].sectors
= (u_char
) min
[2] + 1;
1021 xd_info
[drive
].control
= 0;
1024 /* xd_setup: initialise controller from command line parameters */
1025 static void __init
do_xd_setup (int *integers
)
1027 switch (integers
[0]) {
1028 case 4: if (integers
[4] < 0)
1030 else if (integers
[4] < 8)
1031 xd_dma
= integers
[4];
1032 case 3: if ((integers
[3] > 0) && (integers
[3] <= 0x3FC))
1033 xd_iobase
= integers
[3];
1034 case 2: if ((integers
[2] > 0) && (integers
[2] < 16))
1035 xd_irq
= integers
[2];
1036 case 1: xd_override
= 1;
1037 if ((integers
[1] >= 0) && (integers
[1] < ARRAY_SIZE(xd_sigs
)))
1038 xd_type
= integers
[1];
1040 default:printk("xd: too many parameters for xd\n");
1042 xd_maxsectors
= 0x01;
1045 /* xd_setparam: set the drive characteristics */
1046 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
)
1050 xd_build(cmdblk
,command
,drive
,0,0,0,0,0);
1051 cmdblk
[6] = (u_char
) (cylinders
>> 8) & 0x03;
1052 cmdblk
[7] = (u_char
) (cylinders
& 0xFF);
1053 cmdblk
[8] = heads
& 0x1F;
1054 cmdblk
[9] = (u_char
) (rwrite
>> 8) & 0x03;
1055 cmdblk
[10] = (u_char
) (rwrite
& 0xFF);
1056 cmdblk
[11] = (u_char
) (wprecomp
>> 8) & 0x03;
1057 cmdblk
[12] = (u_char
) (wprecomp
& 0xFF);
1060 /* Some controllers require geometry info as data, not command */
1062 if (xd_command(cmdblk
,PIO_MODE
,NULL
,&cmdblk
[6],NULL
,XD_TIMEOUT
* 2))
1063 printk("xd: error setting characteristics for xd%c\n", 'a'+drive
);
1069 module_param_array(xd
, int, NULL
, 0);
1070 module_param_array(xd_geo
, int, NULL
, 0);
1071 module_param(nodma
, bool, 0);
1073 MODULE_LICENSE("GPL");
1075 void cleanup_module(void)
1078 unregister_blkdev(XT_DISK_MAJOR
, "xd");
1079 for (i
= 0; i
< xd_drives
; i
++) {
1080 del_gendisk(xd_gendisk
[i
]);
1081 put_disk(xd_gendisk
[i
]);
1083 blk_cleanup_queue(xd_queue
);
1084 release_region(xd_iobase
,4);
1086 free_irq(xd_irq
, NULL
);
1089 xd_dma_mem_free((unsigned long)xd_dma_buffer
, xd_maxsectors
* 0x200);
1094 static int __init
xd_setup (char *str
)
1097 get_options (str
, ARRAY_SIZE (ints
), ints
);
1102 /* xd_manual_geo_init: initialise drive geometry from command line parameters
1103 (used only for WD drives) */
1104 static int __init
xd_manual_geo_init (char *str
)
1106 int i
, integers
[1 + 3*XD_MAXDRIVES
];
1108 get_options (str
, ARRAY_SIZE (integers
), integers
);
1109 if (integers
[0]%3 != 0) {
1110 printk("xd: incorrect number of parameters for xd_geo\n");
1113 for (i
= 0; (i
< integers
[0]) && (i
< 3*XD_MAXDRIVES
); i
++)
1114 xd_geo
[i
] = integers
[i
+1];
1118 __setup ("xd=", xd_setup
);
1119 __setup ("xd_geo=", xd_manual_geo_init
);
1123 module_init(xd_init
);
1124 MODULE_ALIAS_BLOCKDEV_MAJOR(XT_DISK_MAJOR
);