2 * This file contains the driver for an XT hard disk controller
3 * (at least the DTC 5150X) for Linux.
5 * Author: Pat Mackinlay, pat@it.com.au
8 * Revised: 01/01/93, ...
10 * Ref: DTC 5150X Controller Specification (thanks to Kevin Fowler,
11 * kevinf@agora.rain.com)
12 * Also thanks to: Salvador Abreu, Dave Thaler, Risto Kankkunen and
15 * Revised: 04/04/94 by Risto Kankkunen
16 * Moved the detection code from xd_init() to xd_geninit() as it needed
17 * interrupts enabled and Linus didn't want to enable them in that first
18 * phase. xd_geninit() is the place to do these kinds of things anyway,
21 * Modularized: 04/10/96 by Todd Fries, tfries@umr.edu
23 * Revised: 13/12/97 by Andrzej Krzysztofowicz, ankry@mif.pg.gda.pl
24 * Fixed some problems with disk initialization and module initiation.
25 * Added support for manual geometry setting (except Seagate controllers)
27 * xd_geo=<cyl_xda>,<head_xda>,<sec_xda>[,<cyl_xdb>,<head_xdb>,<sec_xdb>]
28 * Recovered DMA access. Abridged messages. Added support for DTC5051CX,
29 * WD1002-27X & XEBEC controllers. Driver uses now some jumper settings.
30 * Extended ioctl() support.
32 * Bugfix: 15/02/01, Paul G. - inform queue layer of tiny xd_maxsect.
36 #include <linux/module.h>
37 #include <linux/errno.h>
38 #include <linux/interrupt.h>
41 #include <linux/kernel.h>
42 #include <linux/timer.h>
43 #include <linux/genhd.h>
44 #include <linux/hdreg.h>
45 #include <linux/ioport.h>
46 #include <linux/init.h>
47 #include <linux/wait.h>
48 #include <linux/devfs_fs_kernel.h>
50 #include <asm/system.h>
52 #include <asm/uaccess.h>
55 #define MAJOR_NR XT_DISK_MAJOR
56 #include <linux/blk.h>
57 #include <linux/blkpg.h>
61 static void __init
do_xd_setup (int *integers
);
62 static int xd
[5] = { -1,-1,-1,-1, };
64 #define XD_DONT_USE_DMA 0 /* Initial value. may be overriden using
65 "nodma" module option */
66 #define XD_INIT_DISK_DELAY (30*HZ/1000) /* 30 ms delay during disk initialization */
68 /* Above may need to be increased if a problem with the 2nd drive detection
69 (ST11M controller) or resetting a controller (WD) appears */
71 XD_INFO xd_info
[XD_MAXDRIVES
];
73 /* If you try this driver and find that your card is not detected by the driver at bootup, you need to add your BIOS
74 signature and details to the following list of signatures. A BIOS signature is a string embedded into the first
75 few bytes of your controller's on-board ROM BIOS. To find out what yours is, use something like MS-DOS's DEBUG
76 command. Run DEBUG, and then you can examine your BIOS signature with:
80 where xxxx is the segment of your controller (like C800 or D000 or something). On the ASCII dump at the right, you should
81 be able to see a string mentioning the manufacturer's copyright etc. Add this string into the table below. The parameters
82 in the table are, in order:
84 offset ; this is the offset (in bytes) from the start of your ROM where the signature starts
85 signature ; this is the actual text of the signature
86 xd_?_init_controller ; this is the controller init routine used by your controller
87 xd_?_init_drive ; this is the drive init routine used by your controller
89 The controllers directly supported at the moment are: DTC 5150x, WD 1004A27X, ST11M/R and override. If your controller is
90 made by the same manufacturer as one of these, try using the same init routines as they do. If that doesn't work, your
91 best bet is to use the "override" routines. These routines use a "portable" method of getting the disk's geometry, and
92 may work with your card. If none of these seem to work, try sending me some email and I'll see what I can do <grin>.
94 NOTE: You can now specify your XT controller's parameters from the command line in the form xd=TYPE,IRQ,IO,DMA. The driver
95 should be able to detect your drive's geometry from this info. (eg: xd=0,5,0x320,3 is the "standard"). */
98 #define xd_dma_mem_alloc(size) __get_dma_pages(GFP_KERNEL,get_order(size))
99 #define xd_dma_mem_free(addr, size) free_pages(addr, get_order(size))
100 static char *xd_dma_buffer
= 0;
102 static XD_SIGNATURE xd_sigs
[] __initdata
= {
103 { 0x0000,"Override geometry handler",NULL
,xd_override_init_drive
,"n unknown" }, /* Pat Mackinlay, pat@it.com.au */
104 { 0x0008,"[BXD06 (C) DTC 17-MAY-1985]",xd_dtc_init_controller
,xd_dtc5150cx_init_drive
," DTC 5150CX" }, /* Andrzej Krzysztofowicz, ankry@mif.pg.gda.pl */
105 { 0x000B,"CRD18A Not an IBM rom. (C) Copyright Data Technology Corp. 05/31/88",xd_dtc_init_controller
,xd_dtc_init_drive
," DTC 5150X" }, /* Todd Fries, tfries@umr.edu */
106 { 0x000B,"CXD23A Not an IBM ROM (C)Copyright Data Technology Corp 12/03/88",xd_dtc_init_controller
,xd_dtc_init_drive
," DTC 5150X" }, /* Pat Mackinlay, pat@it.com.au */
107 { 0x0008,"07/15/86(C) Copyright 1986 Western Digital Corp.",xd_wd_init_controller
,xd_wd_init_drive
," Western Dig. 1002-27X" }, /* Andrzej Krzysztofowicz, ankry@mif.pg.gda.pl */
108 { 0x0008,"06/24/88(C) Copyright 1988 Western Digital Corp.",xd_wd_init_controller
,xd_wd_init_drive
," Western Dig. WDXT-GEN2" }, /* Dan Newcombe, newcombe@aa.csc.peachnet.edu */
109 { 0x0015,"SEAGATE ST11 BIOS REVISION",xd_seagate_init_controller
,xd_seagate_init_drive
," Seagate ST11M/R" }, /* Salvador Abreu, spa@fct.unl.pt */
110 { 0x0010,"ST11R BIOS",xd_seagate_init_controller
,xd_seagate_init_drive
," Seagate ST11M/R" }, /* Risto Kankkunen, risto.kankkunen@cs.helsinki.fi */
111 { 0x0010,"ST11 BIOS v1.7",xd_seagate_init_controller
,xd_seagate_init_drive
," Seagate ST11R" }, /* Alan Hourihane, alanh@fairlite.demon.co.uk */
112 { 0x1000,"(c)Copyright 1987 SMS",xd_omti_init_controller
,xd_omti_init_drive
,"n OMTI 5520" }, /* Dirk Melchers, dirk@merlin.nbg.sub.org */
113 { 0x0006,"COPYRIGHT XEBEC (C) 1984",xd_xebec_init_controller
,xd_xebec_init_drive
," XEBEC" }, /* Andrzej Krzysztofowicz, ankry@mif.pg.gda.pl */
114 { 0x0008,"(C) Copyright 1984 Western Digital Corp", xd_wd_init_controller
, xd_wd_init_drive
," Western Dig. 1002s-wx2" },
115 { 0x0008,"(C) Copyright 1986 Western Digital Corporation", xd_wd_init_controller
, xd_wd_init_drive
," 1986 Western Digital" }, /* jfree@sovereign.org */
118 static unsigned int xd_bases
[] __initdata
=
120 0xC8000, 0xCA000, 0xCC000,
121 0xCE000, 0xD0000, 0xD2000,
122 0xD4000, 0xD6000, 0xD8000,
123 0xDA000, 0xDC000, 0xDE000,
127 static spinlock_t xd_lock
= SPIN_LOCK_UNLOCKED
;
129 static struct gendisk
*xd_gendisk
[2];
131 static struct block_device_operations xd_fops
= {
132 .owner
= THIS_MODULE
,
135 static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int
);
136 static u_char xd_drives
, xd_irq
= 5, xd_dma
= 3, xd_maxsectors
;
137 static u_char xd_override __initdata
= 0, xd_type __initdata
= 0;
138 static u_short xd_iobase
= 0x320;
139 static int xd_geo
[XD_MAXDRIVES
*3] __initdata
= { 0, };
141 static volatile int xdc_busy
;
142 static struct timer_list xd_watchdog_int
;
144 static volatile u_char xd_error
;
145 static int nodma
= XD_DONT_USE_DMA
;
147 static struct request_queue xd_queue
;
149 static devfs_handle_t devfs_handle
= NULL
;
151 /* xd_init: register the block device number and set up pointer tables */
152 static int __init
xd_init(void)
156 unsigned int address
;
160 for (i
= 4; i
> 0; i
--)
161 if(((xd
[i
] = xd
[i
-1]) >= 0) && !count
)
167 init_timer (&xd_watchdog_int
); xd_watchdog_int
.function
= xd_watchdog
;
170 xd_dma_buffer
= (char *)xd_dma_mem_alloc(xd_maxsectors
* 0x200);
171 if (!xd_dma_buffer
) {
172 printk(KERN_ERR
"xd: Out of memory.\n");
177 if (register_blkdev(MAJOR_NR
,"xd",&xd_fops
)) {
178 printk("xd: Unable to get major number %d\n",MAJOR_NR
);
181 devfs_handle
= devfs_mk_dir (NULL
, "xd", NULL
);
182 blk_init_queue(&xd_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
);
204 for (i
= 0; i
< xd_drives
; i
++) {
205 XD_INFO
*p
= &xd_info
[i
];
206 struct gendisk
*disk
= alloc_disk(64);
210 disk
->major
= MAJOR_NR
;
211 disk
->first_minor
= i
<<6;
212 sprintf(disk
->disk_name
, "xd%c", i
+'a');
213 disk
->fops
= &xd_fops
;
214 disk
->private_data
= p
;
215 disk
->queue
= &xd_queue
;
216 set_capacity(disk
, p
->heads
* p
->cylinders
* p
->sectors
);
217 printk(" %s: CHS=%d/%d/%d\n", disk
->disk_name
,
218 p
->cylinders
, p
->heads
, p
->sectors
);
219 xd_gendisk
[i
] = disk
;
223 if (request_irq(xd_irq
,xd_interrupt_handler
, 0, "XT hard disk", NULL
)) {
224 printk("xd: unable to get IRQ%d\n",xd_irq
);
228 if (request_dma(xd_dma
,"xd")) {
229 printk("xd: unable to get DMA%d\n",xd_dma
);
233 /* xd_maxsectors depends on controller - so set after detection */
234 blk_queue_max_sectors(&xd_queue
, xd_maxsectors
);
236 for (i
= 0; i
< xd_drives
; i
++)
237 add_disk(xd_gendisk
[i
]);
242 free_irq(xd_irq
, NULL
);
244 for (i
= 0; i
< xd_drives
; i
++)
245 put_disk(xd_gendisk
[i
]);
247 release_region(xd_iobase
,4);
249 blk_cleanup_queue(&xd_queue
);
250 unregister_blkdev(MAJOR_NR
, "xd");
253 xd_dma_mem_free((unsigned long)xd_dma_buffer
,
254 xd_maxsectors
* 0x200);
259 put_disk(xd_gendisk
[i
]);
263 /* xd_detect: scan the possible BIOS ROM locations for the signature strings */
264 static u_char __init
xd_detect (u_char
*controller
, unsigned int *address
)
266 u_char i
,j
,found
= 0;
270 *controller
= xd_type
;
275 for (i
= 0; i
< (sizeof(xd_bases
) / sizeof(xd_bases
[0])) && !found
; i
++)
276 for (j
= 1; j
< (sizeof(xd_sigs
) / sizeof(xd_sigs
[0])) && !found
; j
++)
277 if (isa_check_signature(xd_bases
[i
] + xd_sigs
[j
].offset
,xd_sigs
[j
].string
,strlen(xd_sigs
[j
].string
))) {
280 *address
= xd_bases
[i
];
286 /* do_xd_request: handle an incoming request */
287 static void do_xd_request (request_queue_t
* q
)
292 while (!blk_queue_empty(q
)) {
293 struct request
*req
= elv_next_request(q
);
294 unsigned block
= req
->sector
;
295 unsigned count
= req
->nr_sectors
;
296 int rw
= rq_data_dir(req
);
297 XD_INFO
*disk
= req
->rq_disk
->private_data
;
301 if (!(req
->flags
& REQ_CMD
)) {
305 if (block
+ count
> get_capacity(req
->rq_disk
)) {
309 if (rw
!= READ
&& rw
!= WRITE
) {
310 printk("do_xd_request: unknown request\n");
314 for (retry
= 0; (retry
< XD_RETRIES
) && !res
; retry
++)
315 res
= xd_readwrite(rw
, disk
, req
->buffer
, block
, count
);
316 end_request(req
, res
); /* wrap up, 0 = fail, 1 = success */
320 /* xd_ioctl: handle device ioctl's */
321 static int xd_ioctl (struct inode
*inode
,struct file
*file
,u_int cmd
,u_long arg
)
323 XD_INFO
*p
= inode
->i_bdev
->bd_disk
->private_data
;
328 struct hd_geometry g
;
329 struct hd_geometry
*geometry
= (struct hd_geometry
*) arg
;
331 g
.sectors
= p
->sectors
;
332 g
.cylinders
= p
->cylinders
;
333 g
.start
= get_start_sect(inode
->i_bdev
);
334 return copy_to_user(geometry
, &g
, sizeof g
) ? -EFAULT
: 0;
337 if (!capable(CAP_SYS_ADMIN
)) return -EACCES
;
338 if (xdc_busy
) return -EBUSY
;
340 if (nodma
&& xd_dma_buffer
) {
341 xd_dma_mem_free((unsigned long)xd_dma_buffer
,
342 xd_maxsectors
* 0x200);
344 } else if (!nodma
&& !xd_dma_buffer
) {
345 xd_dma_buffer
= (char *)xd_dma_mem_alloc(xd_maxsectors
* 0x200);
346 if (!xd_dma_buffer
) {
347 nodma
= XD_DONT_USE_DMA
;
353 return put_user(!nodma
, (long *) arg
);
354 case HDIO_GET_MULTCOUNT
:
355 return put_user(xd_maxsectors
, (long *) arg
);
361 /* xd_readwrite: handle a read/write request */
362 static int xd_readwrite (u_char operation
,XD_INFO
*p
,char *buffer
,u_int block
,u_int count
)
365 u_char cmdblk
[6],sense
[4];
366 u_short track
,cylinder
;
367 u_char head
,sector
,control
,mode
= PIO_MODE
,temp
;
371 #ifdef DEBUG_READWRITE
372 printk("xd_readwrite: operation = %s, drive = %d, buffer = 0x%X, block = %d, count = %d\n",operation
== READ
? "read" : "write",drive
,buffer
,block
,count
);
373 #endif /* DEBUG_READWRITE */
375 spin_unlock_irq(&xd_lock
);
377 control
= p
->control
;
379 xd_dma_buffer
= (char *)xd_dma_mem_alloc(xd_maxsectors
* 0x200);
381 temp
= count
< xd_maxsectors
? count
: xd_maxsectors
;
383 track
= block
/ p
->sectors
;
384 head
= track
% p
->heads
;
385 cylinder
= track
/ p
->heads
;
386 sector
= block
% p
->sectors
;
388 #ifdef DEBUG_READWRITE
389 printk("xd_readwrite: drive = %d, head = %d, cylinder = %d, sector = %d, count = %d\n",drive
,head
,cylinder
,sector
,temp
);
390 #endif /* DEBUG_READWRITE */
393 mode
= xd_setup_dma(operation
== READ
? DMA_MODE_READ
: DMA_MODE_WRITE
,(u_char
*)(xd_dma_buffer
),temp
* 0x200);
394 real_buffer
= &xd_dma_buffer
;
395 for (i
=0; i
< (temp
* 0x200); i
++)
396 xd_dma_buffer
[i
] = buffer
[i
];
399 real_buffer
= &buffer
;
401 xd_build(cmdblk
,operation
== READ
? CMD_READ
: CMD_WRITE
,drive
,head
,cylinder
,sector
,temp
& 0xFF,control
);
403 switch (xd_command(cmdblk
,mode
,(u_char
*)(*real_buffer
),(u_char
*)(*real_buffer
),sense
,XD_TIMEOUT
)) {
405 printk("xd%c: %s timeout, recalibrating drive\n",'a'+drive
,(operation
== READ
? "read" : "write"));
406 xd_recalibrate(drive
);
407 spin_lock_irq(&xd_lock
);
410 if (sense
[0] & 0x30) {
411 printk("xd%c: %s - ",'a'+drive
,(operation
== READ
? "reading" : "writing"));
412 switch ((sense
[0] & 0x30) >> 4) {
413 case 0: printk("drive error, code = 0x%X",sense
[0] & 0x0F);
415 case 1: printk("controller error, code = 0x%X",sense
[0] & 0x0F);
417 case 2: printk("command error, code = 0x%X",sense
[0] & 0x0F);
419 case 3: printk("miscellaneous error, code = 0x%X",sense
[0] & 0x0F);
424 printk(" - CHS = %d/%d/%d\n",((sense
[2] & 0xC0) << 2) | sense
[3],sense
[1] & 0x1F,sense
[2] & 0x3F);
425 /* reported drive number = (sense[1] & 0xE0) >> 5 */
427 printk(" - no valid disk address\n");
428 spin_lock_irq(&xd_lock
);
432 for (i
=0; i
< (temp
* 0x200); i
++)
433 buffer
[i
] = xd_dma_buffer
[i
];
435 count
-= temp
, buffer
+= temp
* 0x200, block
+= temp
;
437 spin_lock_irq(&xd_lock
);
441 /* xd_recalibrate: recalibrate a given drive and reset controller if necessary */
442 static void xd_recalibrate (u_char drive
)
446 xd_build(cmdblk
,CMD_RECALIBRATE
,drive
,0,0,0,0,0);
447 if (xd_command(cmdblk
,PIO_MODE
,0,0,0,XD_TIMEOUT
* 8))
448 printk("xd%c: warning! error recalibrating, controller may be unstable\n", 'a'+drive
);
451 /* xd_interrupt_handler: interrupt service routine */
452 static void xd_interrupt_handler(int irq
, void *dev_id
, struct pt_regs
* regs
)
454 if (inb(XD_STATUS
) & STAT_INTERRUPT
) { /* check if it was our device */
456 printk("xd_interrupt_handler: interrupt detected\n");
457 #endif /* DEBUG_OTHER */
458 outb(0,XD_CONTROL
); /* acknowledge interrupt */
459 wake_up(&xd_wait_int
); /* and wake up sleeping processes */
462 printk("xd: unexpected interrupt\n");
465 /* xd_setup_dma: set up the DMA controller for a data transfer */
466 static u_char
xd_setup_dma (u_char mode
,u_char
*buffer
,u_int count
)
472 if (((unsigned long) buffer
& 0xFFFF0000) != (((unsigned long) buffer
+ count
) & 0xFFFF0000)) {
474 printk("xd_setup_dma: using PIO, transfer overlaps 64k boundary\n");
475 #endif /* DEBUG_OTHER */
481 clear_dma_ff(xd_dma
);
482 set_dma_mode(xd_dma
,mode
);
483 set_dma_addr(xd_dma
, (unsigned long) buffer
);
484 set_dma_count(xd_dma
,count
);
488 return (DMA_MODE
); /* use DMA and INT */
491 /* xd_build: put stuff into an array in a format suitable for the controller */
492 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
)
495 cmdblk
[1] = ((drive
& 0x07) << 5) | (head
& 0x1F);
496 cmdblk
[2] = ((cylinder
& 0x300) >> 2) | (sector
& 0x3F);
497 cmdblk
[3] = cylinder
& 0xFF;
504 static void xd_watchdog (unsigned long unused
)
507 wake_up(&xd_wait_int
);
510 /* xd_waitport: waits until port & mask == flags or a timeout occurs. return 1 for a timeout */
511 static inline u_char
xd_waitport (u_short port
,u_char flags
,u_char mask
,u_long timeout
)
513 u_long expiry
= jiffies
+ timeout
;
517 while ((success
= ((inb(port
) & mask
) != flags
)) && time_before(jiffies
, expiry
)) {
518 set_current_state(TASK_UNINTERRUPTIBLE
);
525 static inline u_int
xd_wait_for_IRQ (void)
528 xd_watchdog_int
.expires
= jiffies
+ 8 * HZ
;
529 add_timer(&xd_watchdog_int
);
531 flags
=claim_dma_lock();
533 release_dma_lock(flags
);
535 sleep_on(&xd_wait_int
);
536 del_timer(&xd_watchdog_int
);
539 flags
=claim_dma_lock();
541 release_dma_lock(flags
);
544 printk("xd: missed IRQ - command aborted\n");
551 /* xd_command: handle all data transfers necessary for a single command */
552 static u_int
xd_command (u_char
*command
,u_char mode
,u_char
*indata
,u_char
*outdata
,u_char
*sense
,u_long timeout
)
554 u_char cmdblk
[6],csb
,complete
= 0;
557 printk("xd_command: command = 0x%X, mode = 0x%X, indata = 0x%X, outdata = 0x%X, sense = 0x%X\n",command
,mode
,indata
,outdata
,sense
);
558 #endif /* DEBUG_COMMAND */
561 outb(mode
,XD_CONTROL
);
563 if (xd_waitport(XD_STATUS
,STAT_SELECT
,STAT_SELECT
,timeout
))
567 if (xd_waitport(XD_STATUS
,STAT_READY
,STAT_READY
,timeout
))
570 switch (inb(XD_STATUS
) & (STAT_COMMAND
| STAT_INPUT
)) {
572 if (mode
== DMA_MODE
) {
573 if (xd_wait_for_IRQ())
576 outb(outdata
? *outdata
++ : 0,XD_DATA
);
579 if (mode
== DMA_MODE
) {
580 if (xd_wait_for_IRQ())
584 *indata
++ = inb(XD_DATA
);
589 outb(command
? *command
++ : 0,XD_DATA
);
591 case STAT_COMMAND
| STAT_INPUT
:
598 if (xd_waitport(XD_STATUS
,0,STAT_SELECT
,timeout
)) /* wait until deselected */
601 if (csb
& CSB_ERROR
) { /* read sense data if error */
602 xd_build(cmdblk
,CMD_SENSE
,(csb
& CSB_LUN
) >> 5,0,0,0,0,0);
603 if (xd_command(cmdblk
,0,sense
,0,0,XD_TIMEOUT
))
604 printk("xd: warning! sense command failed!\n");
608 printk("xd_command: completed with csb = 0x%X\n",csb
);
609 #endif /* DEBUG_COMMAND */
611 return (csb
& CSB_ERROR
);
614 static u_char __init
xd_initdrives (void (*init_drive
)(u_char drive
))
616 u_char cmdblk
[6],i
,count
= 0;
618 for (i
= 0; i
< XD_MAXDRIVES
; i
++) {
619 xd_build(cmdblk
,CMD_TESTREADY
,i
,0,0,0,0,0);
620 if (!xd_command(cmdblk
,PIO_MODE
,0,0,0,XD_TIMEOUT
* 8)) {
621 set_current_state(TASK_INTERRUPTIBLE
);
622 schedule_timeout(XD_INIT_DISK_DELAY
);
627 set_current_state(TASK_INTERRUPTIBLE
);
628 schedule_timeout(XD_INIT_DISK_DELAY
);
634 static void __init
xd_manual_geo_set (u_char drive
)
636 xd_info
[drive
].heads
= (u_char
)(xd_geo
[3 * drive
+ 1]);
637 xd_info
[drive
].cylinders
= (u_short
)(xd_geo
[3 * drive
]);
638 xd_info
[drive
].sectors
= (u_char
)(xd_geo
[3 * drive
+ 2]);
641 static void __init
xd_dtc_init_controller (unsigned int address
)
645 case 0xC8000: break; /*initial: 0x320 */
646 case 0xCA000: xd_iobase
= 0x324;
647 case 0xD0000: /*5150CX*/
648 case 0xD8000: break; /*5150CX & 5150XL*/
649 default: printk("xd_dtc_init_controller: unsupported BIOS address %06x\n",address
);
652 xd_maxsectors
= 0x01; /* my card seems to have trouble doing multi-block transfers? */
654 outb(0,XD_RESET
); /* reset the controller */
658 static void __init
xd_dtc5150cx_init_drive (u_char drive
)
660 /* values from controller's BIOS - BIOS chip may be removed */
661 static u_short geometry_table
[][4] = {
662 {0x200,8,0x200,0x100},
663 {0x267,2,0x267,0x267},
664 {0x264,4,0x264,0x80},
666 {0x132,2,0x80, 0x132},
670 {0x132,6,0x80, 0x100},
671 {0x200,6,0x100,0x100},
672 {0x264,2,0x264,0x80},
673 {0x280,4,0x280,0x100},
674 {0x2B9,3,0x2B9,0x2B9},
675 {0x2B9,5,0x2B9,0x2B9},
676 {0x280,6,0x280,0x100},
677 {0x132,4,0x132,0x0}};
681 n
= (drive
? n
: (n
>> 2)) & 0x33;
682 n
= (n
| (n
>> 2)) & 0x0F;
684 xd_manual_geo_set(drive
);
687 xd_info
[drive
].heads
= (u_char
)(geometry_table
[n
][1]); /* heads */
688 xd_info
[drive
].cylinders
= geometry_table
[n
][0]; /* cylinders */
689 xd_info
[drive
].sectors
= 17; /* sectors */
691 xd_info
[drive
].rwrite
= geometry_table
[n
][2]; /* reduced write */
692 xd_info
[drive
].precomp
= geometry_table
[n
][3] /* write precomp */
693 xd_info
[drive
].ecc
= 0x0B; /* ecc length */
697 printk("xd%c: undetermined drive geometry\n",'a'+drive
);
700 xd_info
[drive
].control
= 5; /* control byte */
701 xd_setparam(CMD_DTCSETPARAM
,drive
,xd_info
[drive
].heads
,xd_info
[drive
].cylinders
,geometry_table
[n
][2],geometry_table
[n
][3],0x0B);
702 xd_recalibrate(drive
);
705 static void __init
xd_dtc_init_drive (u_char drive
)
707 u_char cmdblk
[6],buf
[64];
709 xd_build(cmdblk
,CMD_DTCGETGEOM
,drive
,0,0,0,0,0);
710 if (!xd_command(cmdblk
,PIO_MODE
,buf
,0,0,XD_TIMEOUT
* 2)) {
711 xd_info
[drive
].heads
= buf
[0x0A]; /* heads */
712 xd_info
[drive
].cylinders
= ((u_short
*) (buf
))[0x04]; /* cylinders */
713 xd_info
[drive
].sectors
= 17; /* sectors */
715 xd_manual_geo_set(drive
);
717 xd_info
[drive
].rwrite
= ((u_short
*) (buf
+ 1))[0x05]; /* reduced write */
718 xd_info
[drive
].precomp
= ((u_short
*) (buf
+ 1))[0x06]; /* write precomp */
719 xd_info
[drive
].ecc
= buf
[0x0F]; /* ecc length */
721 xd_info
[drive
].control
= 0; /* control byte */
723 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]);
724 xd_build(cmdblk
,CMD_DTCSETSTEP
,drive
,0,0,0,0,7);
725 if (xd_command(cmdblk
,PIO_MODE
,0,0,0,XD_TIMEOUT
* 2))
726 printk("xd_dtc_init_drive: error setting step rate for xd%c\n", 'a'+drive
);
729 printk("xd_dtc_init_drive: error reading geometry for xd%c\n", 'a'+drive
);
732 static void __init
xd_wd_init_controller (unsigned int address
)
736 case 0xC8000: break; /*initial: 0x320 */
737 case 0xCA000: xd_iobase
= 0x324; break;
738 case 0xCC000: xd_iobase
= 0x328; break;
739 case 0xCE000: xd_iobase
= 0x32C; break;
740 case 0xD0000: xd_iobase
= 0x328; break; /* ? */
741 case 0xD8000: xd_iobase
= 0x32C; break; /* ? */
742 default: printk("xd_wd_init_controller: unsupported BIOS address %06x\n",address
);
745 xd_maxsectors
= 0x01; /* this one doesn't wrap properly either... */
747 outb(0,XD_RESET
); /* reset the controller */
749 set_current_state(TASK_UNINTERRUPTIBLE
);
750 schedule_timeout(XD_INIT_DISK_DELAY
);
753 static void __init
xd_wd_init_drive (u_char drive
)
755 /* values from controller's BIOS - BIOS may be disabled */
756 static u_short geometry_table
[][4] = {
757 {0x264,4,0x1C2,0x1C2}, /* common part */
759 {0x267,2,0x1C2,0x1C2},
760 {0x267,4,0x1C2,0x1C2},
762 {0x334,6,0x335,0x335}, /* 1004 series RLL */
763 {0x30E,4,0x30F,0x3DC},
764 {0x30E,2,0x30F,0x30F},
765 {0x267,4,0x268,0x268},
767 {0x3D5,5,0x3D6,0x3D6}, /* 1002 series RLL */
768 {0x3DB,7,0x3DC,0x3DC},
769 {0x264,4,0x265,0x265},
770 {0x267,4,0x268,0x268}};
772 u_char cmdblk
[6],buf
[0x200];
773 u_char n
= 0,rll
,jumper_state
,use_jumper_geo
;
774 u_char wd_1002
= (xd_sigs
[xd_type
].string
[7] == '6');
776 jumper_state
= ~(inb(0x322));
777 if (jumper_state
& 0x40)
779 rll
= (jumper_state
& 0x30) ? (0x04 << wd_1002
) : 0;
780 xd_build(cmdblk
,CMD_READ
,drive
,0,0,0,1,0);
781 if (!xd_command(cmdblk
,PIO_MODE
,buf
,0,0,XD_TIMEOUT
* 2)) {
782 xd_info
[drive
].heads
= buf
[0x1AF]; /* heads */
783 xd_info
[drive
].cylinders
= ((u_short
*) (buf
+ 1))[0xD6]; /* cylinders */
784 xd_info
[drive
].sectors
= 17; /* sectors */
786 xd_manual_geo_set(drive
);
788 xd_info
[drive
].rwrite
= ((u_short
*) (buf
))[0xD8]; /* reduced write */
789 xd_info
[drive
].wprecomp
= ((u_short
*) (buf
))[0xDA]; /* write precomp */
790 xd_info
[drive
].ecc
= buf
[0x1B4]; /* ecc length */
792 xd_info
[drive
].control
= buf
[0x1B5]; /* control byte */
793 use_jumper_geo
= !(xd_info
[drive
].heads
) || !(xd_info
[drive
].cylinders
);
794 if (xd_geo
[3*drive
]) {
795 xd_manual_geo_set(drive
);
796 xd_info
[drive
].control
= rll
? 7 : 5;
798 else if (use_jumper_geo
) {
799 n
= (((jumper_state
& 0x0F) >> (drive
<< 1)) & 0x03) | rll
;
800 xd_info
[drive
].cylinders
= geometry_table
[n
][0];
801 xd_info
[drive
].heads
= (u_char
)(geometry_table
[n
][1]);
802 xd_info
[drive
].control
= rll
? 7 : 5;
804 xd_info
[drive
].rwrite
= geometry_table
[n
][2];
805 xd_info
[drive
].wprecomp
= geometry_table
[n
][3];
806 xd_info
[drive
].ecc
= 0x0B;
811 xd_setparam(CMD_WDSETPARAM
,drive
,xd_info
[drive
].heads
,xd_info
[drive
].cylinders
,
812 geometry_table
[n
][2],geometry_table
[n
][3],0x0B);
814 xd_setparam(CMD_WDSETPARAM
,drive
,xd_info
[drive
].heads
,xd_info
[drive
].cylinders
,
815 ((u_short
*) (buf
))[0xD8],((u_short
*) (buf
))[0xDA],buf
[0x1B4]);
817 /* 1002 based RLL controller requests converted addressing, but reports physical
818 (physical 26 sec., logical 17 sec.)
821 if ((xd_info
[drive
].cylinders
*= 26,
822 xd_info
[drive
].cylinders
/= 17) > 1023)
823 xd_info
[drive
].cylinders
= 1023; /* 1024 ? */
825 xd_info
[drive
].rwrite
*= 26;
826 xd_info
[drive
].rwrite
/= 17;
827 xd_info
[drive
].wprecomp
*= 26
828 xd_info
[drive
].wprecomp
/= 17;
833 printk("xd_wd_init_drive: error reading geometry for xd%c\n",'a'+drive
);
837 static void __init
xd_seagate_init_controller (unsigned int address
)
841 case 0xC8000: break; /*initial: 0x320 */
842 case 0xD0000: xd_iobase
= 0x324; break;
843 case 0xD8000: xd_iobase
= 0x328; break;
844 case 0xE0000: xd_iobase
= 0x32C; break;
845 default: printk("xd_seagate_init_controller: unsupported BIOS address %06x\n",address
);
848 xd_maxsectors
= 0x40;
850 outb(0,XD_RESET
); /* reset the controller */
853 static void __init
xd_seagate_init_drive (u_char drive
)
855 u_char cmdblk
[6],buf
[0x200];
857 xd_build(cmdblk
,CMD_ST11GETGEOM
,drive
,0,0,0,1,0);
858 if (!xd_command(cmdblk
,PIO_MODE
,buf
,0,0,XD_TIMEOUT
* 2)) {
859 xd_info
[drive
].heads
= buf
[0x04]; /* heads */
860 xd_info
[drive
].cylinders
= (buf
[0x02] << 8) | buf
[0x03]; /* cylinders */
861 xd_info
[drive
].sectors
= buf
[0x05]; /* sectors */
862 xd_info
[drive
].control
= 0; /* control byte */
865 printk("xd_seagate_init_drive: error reading geometry from xd%c\n", 'a'+drive
);
868 /* Omti support courtesy Dirk Melchers */
869 static void __init
xd_omti_init_controller (unsigned int address
)
873 case 0xC8000: break; /*initial: 0x320 */
874 case 0xD0000: xd_iobase
= 0x324; break;
875 case 0xD8000: xd_iobase
= 0x328; break;
876 case 0xE0000: xd_iobase
= 0x32C; break;
877 default: printk("xd_omti_init_controller: unsupported BIOS address %06x\n",address
);
881 xd_maxsectors
= 0x40;
883 outb(0,XD_RESET
); /* reset the controller */
886 static void __init
xd_omti_init_drive (u_char drive
)
888 /* gets infos from drive */
889 xd_override_init_drive(drive
);
891 /* set other parameters, Hardcoded, not that nice :-) */
892 xd_info
[drive
].control
= 2;
895 /* Xebec support (AK) */
896 static void __init
xd_xebec_init_controller (unsigned int address
)
898 /* iobase may be set manually in range 0x300 - 0x33C
899 irq may be set manually to 2(9),3,4,5,6,7
900 dma may be set manually to 1,2,3
901 (How to detect them ???)
902 BIOS address may be set manually in range 0x0 - 0xF8000
903 If you need non-standard settings use the xd=... command */
907 case 0xC8000: /* initially: xd_iobase==0x320 */
917 default: printk("xd_xebec_init_controller: unsupported BIOS address %06x\n",address
);
921 xd_maxsectors
= 0x01;
922 outb(0,XD_RESET
); /* reset the controller */
924 set_current_state(TASK_UNINTERRUPTIBLE
);
925 schedule_timeout(XD_INIT_DISK_DELAY
);
928 static void __init
xd_xebec_init_drive (u_char drive
)
930 /* values from controller's BIOS - BIOS chip may be removed */
931 static u_short geometry_table
[][5] = {
932 {0x132,4,0x080,0x080,0x7},
933 {0x132,4,0x080,0x080,0x17},
934 {0x264,2,0x100,0x100,0x7},
935 {0x264,2,0x100,0x100,0x17},
936 {0x132,8,0x080,0x080,0x7},
937 {0x132,8,0x080,0x080,0x17},
938 {0x264,4,0x100,0x100,0x6},
939 {0x264,4,0x100,0x100,0x17},
940 {0x2BC,5,0x2BC,0x12C,0x6},
941 {0x3A5,4,0x3A5,0x3A5,0x7},
942 {0x26C,6,0x26C,0x26C,0x7},
943 {0x200,8,0x200,0x100,0x17},
944 {0x400,5,0x400,0x400,0x7},
945 {0x400,6,0x400,0x400,0x7},
946 {0x264,8,0x264,0x200,0x17},
947 {0x33E,7,0x33E,0x200,0x7}};
950 n
= inb(XD_JUMPER
) & 0x0F; /* BIOS's drive number: same geometry
951 is assumed for BOTH drives */
953 xd_manual_geo_set(drive
);
955 xd_info
[drive
].heads
= (u_char
)(geometry_table
[n
][1]); /* heads */
956 xd_info
[drive
].cylinders
= geometry_table
[n
][0]; /* cylinders */
957 xd_info
[drive
].sectors
= 17; /* sectors */
959 xd_info
[drive
].rwrite
= geometry_table
[n
][2]; /* reduced write */
960 xd_info
[drive
].precomp
= geometry_table
[n
][3] /* write precomp */
961 xd_info
[drive
].ecc
= 0x0B; /* ecc length */
964 xd_info
[drive
].control
= geometry_table
[n
][4]; /* control byte */
965 xd_setparam(CMD_XBSETPARAM
,drive
,xd_info
[drive
].heads
,xd_info
[drive
].cylinders
,geometry_table
[n
][2],geometry_table
[n
][3],0x0B);
966 xd_recalibrate(drive
);
969 /* xd_override_init_drive: this finds disk geometry in a "binary search" style, narrowing in on the "correct" number of heads
970 etc. by trying values until it gets the highest successful value. Idea courtesy Salvador Abreu (spa@fct.unl.pt). */
971 static void __init
xd_override_init_drive (u_char drive
)
973 u_short min
[] = { 0,0,0 },max
[] = { 16,1024,64 },test
[] = { 0,0,0 };
977 xd_manual_geo_set(drive
);
979 for (i
= 0; i
< 3; i
++) {
980 while (min
[i
] != max
[i
] - 1) {
981 test
[i
] = (min
[i
] + max
[i
]) / 2;
982 xd_build(cmdblk
,CMD_SEEK
,drive
,(u_char
) test
[0],(u_short
) test
[1],(u_char
) test
[2],0,0);
983 if (!xd_command(cmdblk
,PIO_MODE
,0,0,0,XD_TIMEOUT
* 2))
990 xd_info
[drive
].heads
= (u_char
) min
[0] + 1;
991 xd_info
[drive
].cylinders
= (u_short
) min
[1] + 1;
992 xd_info
[drive
].sectors
= (u_char
) min
[2] + 1;
994 xd_info
[drive
].control
= 0;
997 /* xd_setup: initialise controller from command line parameters */
998 static void __init
do_xd_setup (int *integers
)
1000 switch (integers
[0]) {
1001 case 4: if (integers
[4] < 0)
1003 else if (integers
[4] < 8)
1004 xd_dma
= integers
[4];
1005 case 3: if ((integers
[3] > 0) && (integers
[3] <= 0x3FC))
1006 xd_iobase
= integers
[3];
1007 case 2: if ((integers
[2] > 0) && (integers
[2] < 16))
1008 xd_irq
= integers
[2];
1009 case 1: xd_override
= 1;
1010 if ((integers
[1] >= 0) && (integers
[1] < (sizeof(xd_sigs
) / sizeof(xd_sigs
[0]))))
1011 xd_type
= integers
[1];
1013 default:printk("xd: too many parameters for xd\n");
1015 xd_maxsectors
= 0x01;
1018 /* xd_setparam: set the drive characteristics */
1019 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
)
1023 xd_build(cmdblk
,command
,drive
,0,0,0,0,0);
1024 cmdblk
[6] = (u_char
) (cylinders
>> 8) & 0x03;
1025 cmdblk
[7] = (u_char
) (cylinders
& 0xFF);
1026 cmdblk
[8] = heads
& 0x1F;
1027 cmdblk
[9] = (u_char
) (rwrite
>> 8) & 0x03;
1028 cmdblk
[10] = (u_char
) (rwrite
& 0xFF);
1029 cmdblk
[11] = (u_char
) (wprecomp
>> 8) & 0x03;
1030 cmdblk
[12] = (u_char
) (wprecomp
& 0xFF);
1033 /* Some controllers require geometry info as data, not command */
1035 if (xd_command(cmdblk
,PIO_MODE
,0,&cmdblk
[6],0,XD_TIMEOUT
* 2))
1036 printk("xd: error setting characteristics for xd%c\n", 'a'+drive
);
1042 MODULE_PARM(xd
, "1-4i");
1043 MODULE_PARM(xd_geo
, "3-6i");
1044 MODULE_PARM(nodma
, "i");
1046 MODULE_LICENSE("GPL");
1048 void cleanup_module(void)
1051 unregister_blkdev(MAJOR_NR
, "xd");
1052 for (i
= 0; i
< xd_drives
; i
++) {
1053 del_gendisk(xd_gendisk
[i
]);
1054 put_disk(xd_gendisk
[i
]);
1056 blk_cleanup_queue(&xd_queue
);
1057 release_region(xd_iobase
,4);
1058 devfs_unregister (devfs_handle
);
1060 free_irq(xd_irq
, NULL
);
1063 xd_dma_mem_free((unsigned long)xd_dma_buffer
, xd_maxsectors
* 0x200);
1068 static int __init
xd_setup (char *str
)
1071 get_options (str
, ARRAY_SIZE (ints
), ints
);
1076 /* xd_manual_geo_init: initialise drive geometry from command line parameters
1077 (used only for WD drives) */
1078 static int __init
xd_manual_geo_init (char *str
)
1080 int i
, integers
[1 + 3*XD_MAXDRIVES
];
1082 get_options (str
, ARRAY_SIZE (integers
), integers
);
1083 if (integers
[0]%3 != 0) {
1084 printk("xd: incorrect number of parameters for xd_geo\n");
1087 for (i
= 0; (i
< integers
[0]) && (i
< 3*XD_MAXDRIVES
); i
++)
1088 xd_geo
[i
] = integers
[i
+1];
1092 __setup ("xd=", xd_setup
);
1093 __setup ("xd_geo=", xd_manual_geo_init
);
1097 module_init(xd_init
)