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/uaccess.h>
60 static DEFINE_MUTEX(xd_mutex
);
61 static void __init
do_xd_setup (int *integers
);
63 static int xd
[5] = { -1,-1,-1,-1, };
66 #define XD_DONT_USE_DMA 0 /* Initial value. may be overriden using
67 "nodma" module option */
68 #define XD_INIT_DISK_DELAY (30) /* 30 ms delay during disk initialization */
70 /* Above may need to be increased if a problem with the 2nd drive detection
71 (ST11M controller) or resetting a controller (WD) appears */
73 static XD_INFO xd_info
[XD_MAXDRIVES
];
75 /* If you try this driver and find that your card is not detected by the driver at bootup, you need to add your BIOS
76 signature and details to the following list of signatures. A BIOS signature is a string embedded into the first
77 few bytes of your controller's on-board ROM BIOS. To find out what yours is, use something like MS-DOS's DEBUG
78 command. Run DEBUG, and then you can examine your BIOS signature with:
82 where xxxx is the segment of your controller (like C800 or D000 or something). On the ASCII dump at the right, you should
83 be able to see a string mentioning the manufacturer's copyright etc. Add this string into the table below. The parameters
84 in the table are, in order:
86 offset ; this is the offset (in bytes) from the start of your ROM where the signature starts
87 signature ; this is the actual text of the signature
88 xd_?_init_controller ; this is the controller init routine used by your controller
89 xd_?_init_drive ; this is the drive init routine used by your controller
91 The controllers directly supported at the moment are: DTC 5150x, WD 1004A27X, ST11M/R and override. If your controller is
92 made by the same manufacturer as one of these, try using the same init routines as they do. If that doesn't work, your
93 best bet is to use the "override" routines. These routines use a "portable" method of getting the disk's geometry, and
94 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>.
96 NOTE: You can now specify your XT controller's parameters from the command line in the form xd=TYPE,IRQ,IO,DMA. The driver
97 should be able to detect your drive's geometry from this info. (eg: xd=0,5,0x320,3 is the "standard"). */
100 #define xd_dma_mem_alloc(size) __get_dma_pages(GFP_KERNEL,get_order(size))
101 #define xd_dma_mem_free(addr, size) free_pages(addr, get_order(size))
102 static char *xd_dma_buffer
;
104 static XD_SIGNATURE xd_sigs
[] __initdata
= {
105 { 0x0000,"Override geometry handler",NULL
,xd_override_init_drive
,"n unknown" }, /* Pat Mackinlay, pat@it.com.au */
106 { 0x0008,"[BXD06 (C) DTC 17-MAY-1985]",xd_dtc_init_controller
,xd_dtc5150cx_init_drive
," DTC 5150CX" }, /* Andrzej Krzysztofowicz, ankry@mif.pg.gda.pl */
107 { 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 */
108 { 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 */
109 { 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 */
110 { 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 */
111 { 0x0015,"SEAGATE ST11 BIOS REVISION",xd_seagate_init_controller
,xd_seagate_init_drive
," Seagate ST11M/R" }, /* Salvador Abreu, spa@fct.unl.pt */
112 { 0x0010,"ST11R BIOS",xd_seagate_init_controller
,xd_seagate_init_drive
," Seagate ST11M/R" }, /* Risto Kankkunen, risto.kankkunen@cs.helsinki.fi */
113 { 0x0010,"ST11 BIOS v1.7",xd_seagate_init_controller
,xd_seagate_init_drive
," Seagate ST11R" }, /* Alan Hourihane, alanh@fairlite.demon.co.uk */
114 { 0x1000,"(c)Copyright 1987 SMS",xd_omti_init_controller
,xd_omti_init_drive
,"n OMTI 5520" }, /* Dirk Melchers, dirk@merlin.nbg.sub.org */
115 { 0x0006,"COPYRIGHT XEBEC (C) 1984",xd_xebec_init_controller
,xd_xebec_init_drive
," XEBEC" }, /* Andrzej Krzysztofowicz, ankry@mif.pg.gda.pl */
116 { 0x0008,"(C) Copyright 1984 Western Digital Corp", xd_wd_init_controller
, xd_wd_init_drive
," Western Dig. 1002s-wx2" },
117 { 0x0008,"(C) Copyright 1986 Western Digital Corporation", xd_wd_init_controller
, xd_wd_init_drive
," 1986 Western Digital" }, /* jfree@sovereign.org */
120 static unsigned int xd_bases
[] __initdata
=
122 0xC8000, 0xCA000, 0xCC000,
123 0xCE000, 0xD0000, 0xD2000,
124 0xD4000, 0xD6000, 0xD8000,
125 0xDA000, 0xDC000, 0xDE000,
129 static DEFINE_SPINLOCK(xd_lock
);
131 static struct gendisk
*xd_gendisk
[2];
133 static int xd_getgeo(struct block_device
*bdev
, struct hd_geometry
*geo
);
135 static const struct block_device_operations xd_fops
= {
136 .owner
= THIS_MODULE
,
140 static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int
);
141 static u_char xd_drives
, xd_irq
= 5, xd_dma
= 3, xd_maxsectors
;
142 static u_char xd_override __initdata
= 0, xd_type __initdata
= 0;
143 static u_short xd_iobase
= 0x320;
144 static int xd_geo
[XD_MAXDRIVES
*3] __initdata
= { 0, };
146 static volatile int xdc_busy
;
147 static struct timer_list xd_watchdog_int
;
149 static volatile u_char xd_error
;
150 static bool nodma
= XD_DONT_USE_DMA
;
152 static struct request_queue
*xd_queue
;
154 /* xd_init: register the block device number and set up pointer tables */
155 static int __init
xd_init(void)
158 unsigned int address
;
164 for (i
= 4; i
> 0; i
--)
165 if (((xd
[i
] = xd
[i
-1]) >= 0) && !count
)
172 init_timer (&xd_watchdog_int
); xd_watchdog_int
.function
= xd_watchdog
;
175 if (register_blkdev(XT_DISK_MAJOR
, "xd"))
179 xd_queue
= blk_init_queue(do_xd_request
, &xd_lock
);
183 if (xd_detect(&controller
,&address
)) {
185 printk("Detected a%s controller (type %d) at address %06x\n",
186 xd_sigs
[controller
].name
,controller
,address
);
187 if (!request_region(xd_iobase
,4,"xd")) {
188 printk("xd: Ports at 0x%x are not available\n",
193 xd_sigs
[controller
].init_controller(address
);
194 xd_drives
= xd_initdrives(xd_sigs
[controller
].init_drive
);
196 printk("Detected %d hard drive%s (using IRQ%d & DMA%d)\n",
197 xd_drives
,xd_drives
== 1 ? "" : "s",xd_irq
,xd_dma
);
201 * With the drive detected, xd_maxsectors should now be known.
202 * If xd_maxsectors is 0, nothing was detected and we fall through
205 if (!xd_dma_buffer
&& xd_maxsectors
) {
206 xd_dma_buffer
= (char *)xd_dma_mem_alloc(xd_maxsectors
* 0x200);
207 if (!xd_dma_buffer
) {
208 printk(KERN_ERR
"xd: Out of memory.\n");
217 for (i
= 0; i
< xd_drives
; i
++) {
218 XD_INFO
*p
= &xd_info
[i
];
219 struct gendisk
*disk
= alloc_disk(64);
223 disk
->major
= XT_DISK_MAJOR
;
224 disk
->first_minor
= i
<<6;
225 sprintf(disk
->disk_name
, "xd%c", i
+'a');
226 disk
->fops
= &xd_fops
;
227 disk
->private_data
= p
;
228 disk
->queue
= xd_queue
;
229 set_capacity(disk
, p
->heads
* p
->cylinders
* p
->sectors
);
230 printk(" %s: CHS=%d/%d/%d\n", disk
->disk_name
,
231 p
->cylinders
, p
->heads
, p
->sectors
);
232 xd_gendisk
[i
] = disk
;
236 if (request_irq(xd_irq
,xd_interrupt_handler
, 0, "XT hard disk", NULL
)) {
237 printk("xd: unable to get IRQ%d\n",xd_irq
);
241 if (request_dma(xd_dma
,"xd")) {
242 printk("xd: unable to get DMA%d\n",xd_dma
);
246 /* xd_maxsectors depends on controller - so set after detection */
247 blk_queue_max_hw_sectors(xd_queue
, xd_maxsectors
);
249 for (i
= 0; i
< xd_drives
; i
++)
250 add_disk(xd_gendisk
[i
]);
255 free_irq(xd_irq
, NULL
);
257 for (i
= 0; i
< xd_drives
; i
++)
258 put_disk(xd_gendisk
[i
]);
261 release_region(xd_iobase
,4);
264 xd_dma_mem_free((unsigned long)xd_dma_buffer
,
265 xd_maxsectors
* 0x200);
267 blk_cleanup_queue(xd_queue
);
269 unregister_blkdev(XT_DISK_MAJOR
, "xd");
275 put_disk(xd_gendisk
[i
]);
279 /* xd_detect: scan the possible BIOS ROM locations for the signature strings */
280 static u_char __init
xd_detect (u_char
*controller
, unsigned int *address
)
286 *controller
= xd_type
;
291 for (i
= 0; i
< ARRAY_SIZE(xd_bases
); i
++) {
292 void __iomem
*p
= ioremap(xd_bases
[i
], 0x2000);
295 for (j
= 1; j
< ARRAY_SIZE(xd_sigs
); j
++) {
296 const char *s
= xd_sigs
[j
].string
;
297 if (check_signature(p
+ xd_sigs
[j
].offset
, s
, strlen(s
))) {
300 *address
= xd_bases
[i
];
310 /* do_xd_request: handle an incoming request */
311 static void do_xd_request (struct request_queue
* q
)
318 req
= blk_fetch_request(q
);
320 unsigned block
= blk_rq_pos(req
);
321 unsigned count
= blk_rq_cur_sectors(req
);
322 XD_INFO
*disk
= req
->rq_disk
->private_data
;
326 if (req
->cmd_type
!= REQ_TYPE_FS
)
328 if (block
+ count
> get_capacity(req
->rq_disk
))
330 for (retry
= 0; (retry
< XD_RETRIES
) && !res
; retry
++)
331 res
= xd_readwrite(rq_data_dir(req
), disk
, req
->buffer
,
334 /* wrap up, 0 = success, -errno = fail */
335 if (!__blk_end_request_cur(req
, res
))
336 req
= blk_fetch_request(q
);
340 static int xd_getgeo(struct block_device
*bdev
, struct hd_geometry
*geo
)
342 XD_INFO
*p
= bdev
->bd_disk
->private_data
;
344 geo
->heads
= p
->heads
;
345 geo
->sectors
= p
->sectors
;
346 geo
->cylinders
= p
->cylinders
;
350 /* xd_ioctl: handle device ioctl's */
351 static int xd_locked_ioctl(struct block_device
*bdev
, fmode_t mode
, u_int cmd
, u_long arg
)
355 if (!capable(CAP_SYS_ADMIN
)) return -EACCES
;
356 if (xdc_busy
) return -EBUSY
;
358 if (nodma
&& xd_dma_buffer
) {
359 xd_dma_mem_free((unsigned long)xd_dma_buffer
,
360 xd_maxsectors
* 0x200);
361 xd_dma_buffer
= NULL
;
362 } else if (!nodma
&& !xd_dma_buffer
) {
363 xd_dma_buffer
= (char *)xd_dma_mem_alloc(xd_maxsectors
* 0x200);
364 if (!xd_dma_buffer
) {
365 nodma
= XD_DONT_USE_DMA
;
371 return put_user(!nodma
, (long __user
*) arg
);
372 case HDIO_GET_MULTCOUNT
:
373 return put_user(xd_maxsectors
, (long __user
*) arg
);
379 static int xd_ioctl(struct block_device
*bdev
, fmode_t mode
,
380 unsigned int cmd
, unsigned long param
)
384 mutex_lock(&xd_mutex
);
385 ret
= xd_locked_ioctl(bdev
, mode
, cmd
, param
);
386 mutex_unlock(&xd_mutex
);
391 /* xd_readwrite: handle a read/write request */
392 static int xd_readwrite (u_char operation
,XD_INFO
*p
,char *buffer
,u_int block
,u_int count
)
395 u_char cmdblk
[6],sense
[4];
396 u_short track
,cylinder
;
397 u_char head
,sector
,control
,mode
= PIO_MODE
,temp
;
401 #ifdef DEBUG_READWRITE
402 printk("xd_readwrite: operation = %s, drive = %d, buffer = 0x%X, block = %d, count = %d\n",operation
== READ
? "read" : "write",drive
,buffer
,block
,count
);
403 #endif /* DEBUG_READWRITE */
405 spin_unlock_irq(&xd_lock
);
407 control
= p
->control
;
409 xd_dma_buffer
= (char *)xd_dma_mem_alloc(xd_maxsectors
* 0x200);
411 temp
= count
< xd_maxsectors
? count
: xd_maxsectors
;
413 track
= block
/ p
->sectors
;
414 head
= track
% p
->heads
;
415 cylinder
= track
/ p
->heads
;
416 sector
= block
% p
->sectors
;
418 #ifdef DEBUG_READWRITE
419 printk("xd_readwrite: drive = %d, head = %d, cylinder = %d, sector = %d, count = %d\n",drive
,head
,cylinder
,sector
,temp
);
420 #endif /* DEBUG_READWRITE */
423 mode
= xd_setup_dma(operation
== READ
? DMA_MODE_READ
: DMA_MODE_WRITE
,(u_char
*)(xd_dma_buffer
),temp
* 0x200);
424 real_buffer
= &xd_dma_buffer
;
425 for (i
=0; i
< (temp
* 0x200); i
++)
426 xd_dma_buffer
[i
] = buffer
[i
];
429 real_buffer
= &buffer
;
431 xd_build(cmdblk
,operation
== READ
? CMD_READ
: CMD_WRITE
,drive
,head
,cylinder
,sector
,temp
& 0xFF,control
);
433 switch (xd_command(cmdblk
,mode
,(u_char
*)(*real_buffer
),(u_char
*)(*real_buffer
),sense
,XD_TIMEOUT
)) {
435 printk("xd%c: %s timeout, recalibrating drive\n",'a'+drive
,(operation
== READ
? "read" : "write"));
436 xd_recalibrate(drive
);
437 spin_lock_irq(&xd_lock
);
440 if (sense
[0] & 0x30) {
441 printk("xd%c: %s - ",'a'+drive
,(operation
== READ
? "reading" : "writing"));
442 switch ((sense
[0] & 0x30) >> 4) {
443 case 0: printk("drive error, code = 0x%X",sense
[0] & 0x0F);
445 case 1: printk("controller error, code = 0x%X",sense
[0] & 0x0F);
447 case 2: printk("command error, code = 0x%X",sense
[0] & 0x0F);
449 case 3: printk("miscellaneous error, code = 0x%X",sense
[0] & 0x0F);
454 printk(" - CHS = %d/%d/%d\n",((sense
[2] & 0xC0) << 2) | sense
[3],sense
[1] & 0x1F,sense
[2] & 0x3F);
455 /* reported drive number = (sense[1] & 0xE0) >> 5 */
457 printk(" - no valid disk address\n");
458 spin_lock_irq(&xd_lock
);
462 for (i
=0; i
< (temp
* 0x200); i
++)
463 buffer
[i
] = xd_dma_buffer
[i
];
465 count
-= temp
, buffer
+= temp
* 0x200, block
+= temp
;
467 spin_lock_irq(&xd_lock
);
471 /* xd_recalibrate: recalibrate a given drive and reset controller if necessary */
472 static void xd_recalibrate (u_char drive
)
476 xd_build(cmdblk
,CMD_RECALIBRATE
,drive
,0,0,0,0,0);
477 if (xd_command(cmdblk
,PIO_MODE
,NULL
,NULL
,NULL
,XD_TIMEOUT
* 8))
478 printk("xd%c: warning! error recalibrating, controller may be unstable\n", 'a'+drive
);
481 /* xd_interrupt_handler: interrupt service routine */
482 static irqreturn_t
xd_interrupt_handler(int irq
, void *dev_id
)
484 if (inb(XD_STATUS
) & STAT_INTERRUPT
) { /* check if it was our device */
486 printk("xd_interrupt_handler: interrupt detected\n");
487 #endif /* DEBUG_OTHER */
488 outb(0,XD_CONTROL
); /* acknowledge interrupt */
489 wake_up(&xd_wait_int
); /* and wake up sleeping processes */
493 printk("xd: unexpected interrupt\n");
497 /* xd_setup_dma: set up the DMA controller for a data transfer */
498 static u_char
xd_setup_dma (u_char mode
,u_char
*buffer
,u_int count
)
504 if (((unsigned long) buffer
& 0xFFFF0000) != (((unsigned long) buffer
+ count
) & 0xFFFF0000)) {
506 printk("xd_setup_dma: using PIO, transfer overlaps 64k boundary\n");
507 #endif /* DEBUG_OTHER */
513 clear_dma_ff(xd_dma
);
514 set_dma_mode(xd_dma
,mode
);
515 set_dma_addr(xd_dma
, (unsigned long) buffer
);
516 set_dma_count(xd_dma
,count
);
520 return (DMA_MODE
); /* use DMA and INT */
523 /* xd_build: put stuff into an array in a format suitable for the controller */
524 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
)
527 cmdblk
[1] = ((drive
& 0x07) << 5) | (head
& 0x1F);
528 cmdblk
[2] = ((cylinder
& 0x300) >> 2) | (sector
& 0x3F);
529 cmdblk
[3] = cylinder
& 0xFF;
536 static void xd_watchdog (unsigned long unused
)
539 wake_up(&xd_wait_int
);
542 /* xd_waitport: waits until port & mask == flags or a timeout occurs. return 1 for a timeout */
543 static inline u_char
xd_waitport (u_short port
,u_char flags
,u_char mask
,u_long timeout
)
545 u_long expiry
= jiffies
+ timeout
;
549 while ((success
= ((inb(port
) & mask
) != flags
)) && time_before(jiffies
, expiry
))
550 schedule_timeout_uninterruptible(1);
555 static inline u_int
xd_wait_for_IRQ (void)
558 xd_watchdog_int
.expires
= jiffies
+ 8 * HZ
;
559 add_timer(&xd_watchdog_int
);
561 flags
=claim_dma_lock();
563 release_dma_lock(flags
);
565 sleep_on(&xd_wait_int
);
566 del_timer(&xd_watchdog_int
);
569 flags
=claim_dma_lock();
571 release_dma_lock(flags
);
574 printk("xd: missed IRQ - command aborted\n");
581 /* xd_command: handle all data transfers necessary for a single command */
582 static u_int
xd_command (u_char
*command
,u_char mode
,u_char
*indata
,u_char
*outdata
,u_char
*sense
,u_long timeout
)
584 u_char cmdblk
[6],csb
,complete
= 0;
587 printk("xd_command: command = 0x%X, mode = 0x%X, indata = 0x%X, outdata = 0x%X, sense = 0x%X\n",command
,mode
,indata
,outdata
,sense
);
588 #endif /* DEBUG_COMMAND */
591 outb(mode
,XD_CONTROL
);
593 if (xd_waitport(XD_STATUS
,STAT_SELECT
,STAT_SELECT
,timeout
))
597 if (xd_waitport(XD_STATUS
,STAT_READY
,STAT_READY
,timeout
))
600 switch (inb(XD_STATUS
) & (STAT_COMMAND
| STAT_INPUT
)) {
602 if (mode
== DMA_MODE
) {
603 if (xd_wait_for_IRQ())
606 outb(outdata
? *outdata
++ : 0,XD_DATA
);
609 if (mode
== DMA_MODE
) {
610 if (xd_wait_for_IRQ())
614 *indata
++ = inb(XD_DATA
);
619 outb(command
? *command
++ : 0,XD_DATA
);
621 case STAT_COMMAND
| STAT_INPUT
:
628 if (xd_waitport(XD_STATUS
,0,STAT_SELECT
,timeout
)) /* wait until deselected */
631 if (csb
& CSB_ERROR
) { /* read sense data if error */
632 xd_build(cmdblk
,CMD_SENSE
,(csb
& CSB_LUN
) >> 5,0,0,0,0,0);
633 if (xd_command(cmdblk
,0,sense
,NULL
,NULL
,XD_TIMEOUT
))
634 printk("xd: warning! sense command failed!\n");
638 printk("xd_command: completed with csb = 0x%X\n",csb
);
639 #endif /* DEBUG_COMMAND */
641 return (csb
& CSB_ERROR
);
644 static u_char __init
xd_initdrives (void (*init_drive
)(u_char drive
))
646 u_char cmdblk
[6],i
,count
= 0;
648 for (i
= 0; i
< XD_MAXDRIVES
; i
++) {
649 xd_build(cmdblk
,CMD_TESTREADY
,i
,0,0,0,0,0);
650 if (!xd_command(cmdblk
,PIO_MODE
,NULL
,NULL
,NULL
,XD_TIMEOUT
*8)) {
651 msleep_interruptible(XD_INIT_DISK_DELAY
);
656 msleep_interruptible(XD_INIT_DISK_DELAY
);
662 static void __init
xd_manual_geo_set (u_char drive
)
664 xd_info
[drive
].heads
= (u_char
)(xd_geo
[3 * drive
+ 1]);
665 xd_info
[drive
].cylinders
= (u_short
)(xd_geo
[3 * drive
]);
666 xd_info
[drive
].sectors
= (u_char
)(xd_geo
[3 * drive
+ 2]);
669 static void __init
xd_dtc_init_controller (unsigned int address
)
673 case 0xC8000: break; /*initial: 0x320 */
674 case 0xCA000: xd_iobase
= 0x324;
675 case 0xD0000: /*5150CX*/
676 case 0xD8000: break; /*5150CX & 5150XL*/
677 default: printk("xd_dtc_init_controller: unsupported BIOS address %06x\n",address
);
680 xd_maxsectors
= 0x01; /* my card seems to have trouble doing multi-block transfers? */
682 outb(0,XD_RESET
); /* reset the controller */
686 static void __init
xd_dtc5150cx_init_drive (u_char drive
)
688 /* values from controller's BIOS - BIOS chip may be removed */
689 static u_short geometry_table
[][4] = {
690 {0x200,8,0x200,0x100},
691 {0x267,2,0x267,0x267},
692 {0x264,4,0x264,0x80},
694 {0x132,2,0x80, 0x132},
698 {0x132,6,0x80, 0x100},
699 {0x200,6,0x100,0x100},
700 {0x264,2,0x264,0x80},
701 {0x280,4,0x280,0x100},
702 {0x2B9,3,0x2B9,0x2B9},
703 {0x2B9,5,0x2B9,0x2B9},
704 {0x280,6,0x280,0x100},
705 {0x132,4,0x132,0x0}};
709 n
= (drive
? n
: (n
>> 2)) & 0x33;
710 n
= (n
| (n
>> 2)) & 0x0F;
712 xd_manual_geo_set(drive
);
715 xd_info
[drive
].heads
= (u_char
)(geometry_table
[n
][1]); /* heads */
716 xd_info
[drive
].cylinders
= geometry_table
[n
][0]; /* cylinders */
717 xd_info
[drive
].sectors
= 17; /* sectors */
719 xd_info
[drive
].rwrite
= geometry_table
[n
][2]; /* reduced write */
720 xd_info
[drive
].precomp
= geometry_table
[n
][3] /* write precomp */
721 xd_info
[drive
].ecc
= 0x0B; /* ecc length */
725 printk("xd%c: undetermined drive geometry\n",'a'+drive
);
728 xd_info
[drive
].control
= 5; /* control byte */
729 xd_setparam(CMD_DTCSETPARAM
,drive
,xd_info
[drive
].heads
,xd_info
[drive
].cylinders
,geometry_table
[n
][2],geometry_table
[n
][3],0x0B);
730 xd_recalibrate(drive
);
733 static void __init
xd_dtc_init_drive (u_char drive
)
735 u_char cmdblk
[6],buf
[64];
737 xd_build(cmdblk
,CMD_DTCGETGEOM
,drive
,0,0,0,0,0);
738 if (!xd_command(cmdblk
,PIO_MODE
,buf
,NULL
,NULL
,XD_TIMEOUT
* 2)) {
739 xd_info
[drive
].heads
= buf
[0x0A]; /* heads */
740 xd_info
[drive
].cylinders
= ((u_short
*) (buf
))[0x04]; /* cylinders */
741 xd_info
[drive
].sectors
= 17; /* sectors */
743 xd_manual_geo_set(drive
);
745 xd_info
[drive
].rwrite
= ((u_short
*) (buf
+ 1))[0x05]; /* reduced write */
746 xd_info
[drive
].precomp
= ((u_short
*) (buf
+ 1))[0x06]; /* write precomp */
747 xd_info
[drive
].ecc
= buf
[0x0F]; /* ecc length */
749 xd_info
[drive
].control
= 0; /* control byte */
751 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]);
752 xd_build(cmdblk
,CMD_DTCSETSTEP
,drive
,0,0,0,0,7);
753 if (xd_command(cmdblk
,PIO_MODE
,NULL
,NULL
,NULL
,XD_TIMEOUT
* 2))
754 printk("xd_dtc_init_drive: error setting step rate for xd%c\n", 'a'+drive
);
757 printk("xd_dtc_init_drive: error reading geometry for xd%c\n", 'a'+drive
);
760 static void __init
xd_wd_init_controller (unsigned int address
)
764 case 0xC8000: break; /*initial: 0x320 */
765 case 0xCA000: xd_iobase
= 0x324; break;
766 case 0xCC000: xd_iobase
= 0x328; break;
767 case 0xCE000: xd_iobase
= 0x32C; break;
768 case 0xD0000: xd_iobase
= 0x328; break; /* ? */
769 case 0xD8000: xd_iobase
= 0x32C; break; /* ? */
770 default: printk("xd_wd_init_controller: unsupported BIOS address %06x\n",address
);
773 xd_maxsectors
= 0x01; /* this one doesn't wrap properly either... */
775 outb(0,XD_RESET
); /* reset the controller */
777 msleep(XD_INIT_DISK_DELAY
);
780 static void __init
xd_wd_init_drive (u_char drive
)
782 /* values from controller's BIOS - BIOS may be disabled */
783 static u_short geometry_table
[][4] = {
784 {0x264,4,0x1C2,0x1C2}, /* common part */
786 {0x267,2,0x1C2,0x1C2},
787 {0x267,4,0x1C2,0x1C2},
789 {0x334,6,0x335,0x335}, /* 1004 series RLL */
790 {0x30E,4,0x30F,0x3DC},
791 {0x30E,2,0x30F,0x30F},
792 {0x267,4,0x268,0x268},
794 {0x3D5,5,0x3D6,0x3D6}, /* 1002 series RLL */
795 {0x3DB,7,0x3DC,0x3DC},
796 {0x264,4,0x265,0x265},
797 {0x267,4,0x268,0x268}};
799 u_char cmdblk
[6],buf
[0x200];
800 u_char n
= 0,rll
,jumper_state
,use_jumper_geo
;
801 u_char wd_1002
= (xd_sigs
[xd_type
].string
[7] == '6');
803 jumper_state
= ~(inb(0x322));
804 if (jumper_state
& 0x40)
806 rll
= (jumper_state
& 0x30) ? (0x04 << wd_1002
) : 0;
807 xd_build(cmdblk
,CMD_READ
,drive
,0,0,0,1,0);
808 if (!xd_command(cmdblk
,PIO_MODE
,buf
,NULL
,NULL
,XD_TIMEOUT
* 2)) {
809 xd_info
[drive
].heads
= buf
[0x1AF]; /* heads */
810 xd_info
[drive
].cylinders
= ((u_short
*) (buf
+ 1))[0xD6]; /* cylinders */
811 xd_info
[drive
].sectors
= 17; /* sectors */
813 xd_manual_geo_set(drive
);
815 xd_info
[drive
].rwrite
= ((u_short
*) (buf
))[0xD8]; /* reduced write */
816 xd_info
[drive
].wprecomp
= ((u_short
*) (buf
))[0xDA]; /* write precomp */
817 xd_info
[drive
].ecc
= buf
[0x1B4]; /* ecc length */
819 xd_info
[drive
].control
= buf
[0x1B5]; /* control byte */
820 use_jumper_geo
= !(xd_info
[drive
].heads
) || !(xd_info
[drive
].cylinders
);
821 if (xd_geo
[3*drive
]) {
822 xd_manual_geo_set(drive
);
823 xd_info
[drive
].control
= rll
? 7 : 5;
825 else if (use_jumper_geo
) {
826 n
= (((jumper_state
& 0x0F) >> (drive
<< 1)) & 0x03) | rll
;
827 xd_info
[drive
].cylinders
= geometry_table
[n
][0];
828 xd_info
[drive
].heads
= (u_char
)(geometry_table
[n
][1]);
829 xd_info
[drive
].control
= rll
? 7 : 5;
831 xd_info
[drive
].rwrite
= geometry_table
[n
][2];
832 xd_info
[drive
].wprecomp
= geometry_table
[n
][3];
833 xd_info
[drive
].ecc
= 0x0B;
838 xd_setparam(CMD_WDSETPARAM
,drive
,xd_info
[drive
].heads
,xd_info
[drive
].cylinders
,
839 geometry_table
[n
][2],geometry_table
[n
][3],0x0B);
841 xd_setparam(CMD_WDSETPARAM
,drive
,xd_info
[drive
].heads
,xd_info
[drive
].cylinders
,
842 ((u_short
*) (buf
))[0xD8],((u_short
*) (buf
))[0xDA],buf
[0x1B4]);
844 /* 1002 based RLL controller requests converted addressing, but reports physical
845 (physical 26 sec., logical 17 sec.)
848 if ((xd_info
[drive
].cylinders
*= 26,
849 xd_info
[drive
].cylinders
/= 17) > 1023)
850 xd_info
[drive
].cylinders
= 1023; /* 1024 ? */
852 xd_info
[drive
].rwrite
*= 26;
853 xd_info
[drive
].rwrite
/= 17;
854 xd_info
[drive
].wprecomp
*= 26
855 xd_info
[drive
].wprecomp
/= 17;
860 printk("xd_wd_init_drive: error reading geometry for xd%c\n",'a'+drive
);
864 static void __init
xd_seagate_init_controller (unsigned int address
)
868 case 0xC8000: break; /*initial: 0x320 */
869 case 0xD0000: xd_iobase
= 0x324; break;
870 case 0xD8000: xd_iobase
= 0x328; break;
871 case 0xE0000: xd_iobase
= 0x32C; break;
872 default: printk("xd_seagate_init_controller: unsupported BIOS address %06x\n",address
);
875 xd_maxsectors
= 0x40;
877 outb(0,XD_RESET
); /* reset the controller */
880 static void __init
xd_seagate_init_drive (u_char drive
)
882 u_char cmdblk
[6],buf
[0x200];
884 xd_build(cmdblk
,CMD_ST11GETGEOM
,drive
,0,0,0,1,0);
885 if (!xd_command(cmdblk
,PIO_MODE
,buf
,NULL
,NULL
,XD_TIMEOUT
* 2)) {
886 xd_info
[drive
].heads
= buf
[0x04]; /* heads */
887 xd_info
[drive
].cylinders
= (buf
[0x02] << 8) | buf
[0x03]; /* cylinders */
888 xd_info
[drive
].sectors
= buf
[0x05]; /* sectors */
889 xd_info
[drive
].control
= 0; /* control byte */
892 printk("xd_seagate_init_drive: error reading geometry from xd%c\n", 'a'+drive
);
895 /* Omti support courtesy Dirk Melchers */
896 static void __init
xd_omti_init_controller (unsigned int address
)
900 case 0xC8000: break; /*initial: 0x320 */
901 case 0xD0000: xd_iobase
= 0x324; break;
902 case 0xD8000: xd_iobase
= 0x328; break;
903 case 0xE0000: xd_iobase
= 0x32C; break;
904 default: printk("xd_omti_init_controller: unsupported BIOS address %06x\n",address
);
908 xd_maxsectors
= 0x40;
910 outb(0,XD_RESET
); /* reset the controller */
913 static void __init
xd_omti_init_drive (u_char drive
)
915 /* gets infos from drive */
916 xd_override_init_drive(drive
);
918 /* set other parameters, Hardcoded, not that nice :-) */
919 xd_info
[drive
].control
= 2;
922 /* Xebec support (AK) */
923 static void __init
xd_xebec_init_controller (unsigned int address
)
925 /* iobase may be set manually in range 0x300 - 0x33C
926 irq may be set manually to 2(9),3,4,5,6,7
927 dma may be set manually to 1,2,3
928 (How to detect them ???)
929 BIOS address may be set manually in range 0x0 - 0xF8000
930 If you need non-standard settings use the xd=... command */
934 case 0xC8000: /* initially: xd_iobase==0x320 */
944 default: printk("xd_xebec_init_controller: unsupported BIOS address %06x\n",address
);
948 xd_maxsectors
= 0x01;
949 outb(0,XD_RESET
); /* reset the controller */
951 msleep(XD_INIT_DISK_DELAY
);
954 static void __init
xd_xebec_init_drive (u_char drive
)
956 /* values from controller's BIOS - BIOS chip may be removed */
957 static u_short geometry_table
[][5] = {
958 {0x132,4,0x080,0x080,0x7},
959 {0x132,4,0x080,0x080,0x17},
960 {0x264,2,0x100,0x100,0x7},
961 {0x264,2,0x100,0x100,0x17},
962 {0x132,8,0x080,0x080,0x7},
963 {0x132,8,0x080,0x080,0x17},
964 {0x264,4,0x100,0x100,0x6},
965 {0x264,4,0x100,0x100,0x17},
966 {0x2BC,5,0x2BC,0x12C,0x6},
967 {0x3A5,4,0x3A5,0x3A5,0x7},
968 {0x26C,6,0x26C,0x26C,0x7},
969 {0x200,8,0x200,0x100,0x17},
970 {0x400,5,0x400,0x400,0x7},
971 {0x400,6,0x400,0x400,0x7},
972 {0x264,8,0x264,0x200,0x17},
973 {0x33E,7,0x33E,0x200,0x7}};
976 n
= inb(XD_JUMPER
) & 0x0F; /* BIOS's drive number: same geometry
977 is assumed for BOTH drives */
979 xd_manual_geo_set(drive
);
981 xd_info
[drive
].heads
= (u_char
)(geometry_table
[n
][1]); /* heads */
982 xd_info
[drive
].cylinders
= geometry_table
[n
][0]; /* cylinders */
983 xd_info
[drive
].sectors
= 17; /* sectors */
985 xd_info
[drive
].rwrite
= geometry_table
[n
][2]; /* reduced write */
986 xd_info
[drive
].precomp
= geometry_table
[n
][3] /* write precomp */
987 xd_info
[drive
].ecc
= 0x0B; /* ecc length */
990 xd_info
[drive
].control
= geometry_table
[n
][4]; /* control byte */
991 xd_setparam(CMD_XBSETPARAM
,drive
,xd_info
[drive
].heads
,xd_info
[drive
].cylinders
,geometry_table
[n
][2],geometry_table
[n
][3],0x0B);
992 xd_recalibrate(drive
);
995 /* xd_override_init_drive: this finds disk geometry in a "binary search" style, narrowing in on the "correct" number of heads
996 etc. by trying values until it gets the highest successful value. Idea courtesy Salvador Abreu (spa@fct.unl.pt). */
997 static void __init
xd_override_init_drive (u_char drive
)
999 u_short min
[] = { 0,0,0 },max
[] = { 16,1024,64 },test
[] = { 0,0,0 };
1002 if (xd_geo
[3*drive
])
1003 xd_manual_geo_set(drive
);
1005 for (i
= 0; i
< 3; i
++) {
1006 while (min
[i
] != max
[i
] - 1) {
1007 test
[i
] = (min
[i
] + max
[i
]) / 2;
1008 xd_build(cmdblk
,CMD_SEEK
,drive
,(u_char
) test
[0],(u_short
) test
[1],(u_char
) test
[2],0,0);
1009 if (!xd_command(cmdblk
,PIO_MODE
,NULL
,NULL
,NULL
,XD_TIMEOUT
* 2))
1016 xd_info
[drive
].heads
= (u_char
) min
[0] + 1;
1017 xd_info
[drive
].cylinders
= (u_short
) min
[1] + 1;
1018 xd_info
[drive
].sectors
= (u_char
) min
[2] + 1;
1020 xd_info
[drive
].control
= 0;
1023 /* xd_setup: initialise controller from command line parameters */
1024 static void __init
do_xd_setup (int *integers
)
1026 switch (integers
[0]) {
1027 case 4: if (integers
[4] < 0)
1029 else if (integers
[4] < 8)
1030 xd_dma
= integers
[4];
1031 case 3: if ((integers
[3] > 0) && (integers
[3] <= 0x3FC))
1032 xd_iobase
= integers
[3];
1033 case 2: if ((integers
[2] > 0) && (integers
[2] < 16))
1034 xd_irq
= integers
[2];
1035 case 1: xd_override
= 1;
1036 if ((integers
[1] >= 0) && (integers
[1] < ARRAY_SIZE(xd_sigs
)))
1037 xd_type
= integers
[1];
1039 default:printk("xd: too many parameters for xd\n");
1041 xd_maxsectors
= 0x01;
1044 /* xd_setparam: set the drive characteristics */
1045 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
)
1049 xd_build(cmdblk
,command
,drive
,0,0,0,0,0);
1050 cmdblk
[6] = (u_char
) (cylinders
>> 8) & 0x03;
1051 cmdblk
[7] = (u_char
) (cylinders
& 0xFF);
1052 cmdblk
[8] = heads
& 0x1F;
1053 cmdblk
[9] = (u_char
) (rwrite
>> 8) & 0x03;
1054 cmdblk
[10] = (u_char
) (rwrite
& 0xFF);
1055 cmdblk
[11] = (u_char
) (wprecomp
>> 8) & 0x03;
1056 cmdblk
[12] = (u_char
) (wprecomp
& 0xFF);
1059 /* Some controllers require geometry info as data, not command */
1061 if (xd_command(cmdblk
,PIO_MODE
,NULL
,&cmdblk
[6],NULL
,XD_TIMEOUT
* 2))
1062 printk("xd: error setting characteristics for xd%c\n", 'a'+drive
);
1068 module_param_array(xd
, int, NULL
, 0);
1069 module_param_array(xd_geo
, int, NULL
, 0);
1070 module_param(nodma
, bool, 0);
1072 MODULE_LICENSE("GPL");
1074 void cleanup_module(void)
1077 unregister_blkdev(XT_DISK_MAJOR
, "xd");
1078 for (i
= 0; i
< xd_drives
; i
++) {
1079 del_gendisk(xd_gendisk
[i
]);
1080 put_disk(xd_gendisk
[i
]);
1082 blk_cleanup_queue(xd_queue
);
1083 release_region(xd_iobase
,4);
1085 free_irq(xd_irq
, NULL
);
1088 xd_dma_mem_free((unsigned long)xd_dma_buffer
, xd_maxsectors
* 0x200);
1093 static int __init
xd_setup (char *str
)
1096 get_options (str
, ARRAY_SIZE (ints
), ints
);
1101 /* xd_manual_geo_init: initialise drive geometry from command line parameters
1102 (used only for WD drives) */
1103 static int __init
xd_manual_geo_init (char *str
)
1105 int i
, integers
[1 + 3*XD_MAXDRIVES
];
1107 get_options (str
, ARRAY_SIZE (integers
), integers
);
1108 if (integers
[0]%3 != 0) {
1109 printk("xd: incorrect number of parameters for xd_geo\n");
1112 for (i
= 0; (i
< integers
[0]) && (i
< 3*XD_MAXDRIVES
); i
++)
1113 xd_geo
[i
] = integers
[i
+1];
1117 __setup ("xd=", xd_setup
);
1118 __setup ("xd_geo=", xd_manual_geo_init
);
1122 module_init(xd_init
);
1123 MODULE_ALIAS_BLOCKDEV_MAJOR(XT_DISK_MAJOR
);